私はプログラミング言語のインタープリターを実装しようとしていますが、後戻りする必要があるケースに出くわしましたが、私のパーサージェネレーター (ply、Python で書かれた lex&yacc クローン) はそれを許可しません。関係するルールは次のとおりです:
'var_access_start : super'
'var_access_start : NAME'
'var_access_name : DOT NAME'
'var_access_idx : OPSQR expression CLSQR'
'''callargs : callargs COMMA expression
| expression
| '''
'var_access_metcall : DOT NAME LPAREN callargs RPAREN'
'''var_access_token : var_access_name
| var_access_idx
| var_access_metcall'''
'''var_access_tokens : var_access_tokens var_access_token
| var_access_token'''
'''fornew_var_access_tokens : var_access_tokens var_access_name
| var_access_tokens var_access_idx
| var_access_name
| var_access_idx'''
'type_varref : var_access_start fornew_var_access_tokens'
'hard_varref : var_access_start var_access_tokens'
'easy_varref : var_access_start'
'varref : easy_varref'
'varref : hard_varref'
'typereference : NAME'
'typereference : type_varref'
'''expression : new typereference LPAREN callargs RPAREN'''
'var_decl_empty : NAME'
'var_decl_value : NAME EQUALS expression'
'''var_decl : var_decl_empty
| var_decl_value'''
'''var_decls : var_decls COMMA var_decl
| var_decl'''
'statement : var var_decls SEMIC'
エラーは、フォームのステートメントで発生します
var x = new SomeGuy.SomeOtherGuy();
SomeGuy.SomeOtherGuy は、型を格納する有効な変数です (型はファースト クラス オブジェクトです)。その型には、引数のないコンストラクターがあります。
その式を解析すると、パーサーは var_access_start = SomeGuy var_access_metcall = を構築します。SomeOtherGuy ( ) を実行し、セミコロンを見つけてエラー状態で終了します - パーサーがバックトラックして、式 = new typereference(SomeGuy .SomeOtherGuy) LPAREN empty_list RPAREN を作成してみてください。var ステートメントの構文と完全に一致します
ただし、PLY はバックトラッキングをサポートしておらず、パーサー ジェネレーターで実際に自分で実装するのに十分な経験がないことを考えると、問題を回避するために文法に変更を加えることはできますか?
の代わりに -> を使用することを検討しました。「メソッド呼び出し」演算子としてですが、パーサーをなだめるためだけに言語を変更したくありません。また、「変数参照」の形式としてメソッドがあるため、 myObject.someMethod().aChildOfTheResult[0].doSomeOtherThing(1,2,3).helloWorld() を実行できますが、文法を修正して同じ効果、それも私のために働くだろう
ありがとう!