私は単純なSQLのようなクエリパーサーのような選択をしており、文字通り特定の場所で発生するサブクエリをキャプチャできるようにする必要があります。私はレクサー州が最善の解決策であり、中括弧を使用して開始点と終了点をマークするPOCを実行できることを発見しました。ただし、サブクエリはカッコではなくカッコで区切られ、カッコは他の場所でも発生する可能性があるため、オープンparenの状態はすべてできません。この情報はパーサですぐに利用できるので、パーサルールの適切な場所でbeginとendを呼び出すことを望んでいました。これは、しかし、レクサーが一度にストリームをトークン化するように見えるので、動作しませんでした。そのため、トークンはINITIAL状態で生成されます。この問題の回避策はありますか?パーサーからのPython PLYレクサー状態の制御
def p_value_subquery(p):
"""
value : start_sub end_sub
"""
p[0] = "(" + p[1] + ")"
def p_start_sub(p):
"""
start_sub : OPAR
"""
start_subquery(p.lexer)
p[0] = p[1]
def p_end_sub(p):
"""
end_sub : CPAR
"""
subquery = end_subquery(p.lexer)
p[0] = subquery
start_subquery()とend_subqueryを()のように定義されています:ここで私はやってみました何の概要は
def start_subquery(lexer):
lexer.code_start = lexer.lexpos # Record the starting position
lexer.level = 1
lexer.begin('subquery')
def end_subquery(lexer):
value = lexer.lexdata[lexer.code_start:lexer.lexpos-1]
lexer.lineno += value.count('\n')
lexer.begin('INITIAL')
return value
レクサー・トークンは、クローズ括弧を検出するだけです:
@lex.TOKEN(r"\(")
def t_subquery_SUBQST(t):
lexer.level += 1
@lex.TOKEN(r"\)")
def t_subquery_SUBQEN(t):
lexer.level -= 1
@lex.TOKEN(r".")
def t_subquery_anychar(t):
pass
私は何か助けていただきありがとうございます。
dmbeddedアクションへのポインタありがとうございます。非常に有望です。しかし、あなたの例では、最後のトークンの代わりに先読みトークンをチェックすることになっていますか?最後のトークンは 'B'ですが、先読みは' LBRACE'でしょうか? – haridsv