我正在尝试为一种编程语言实现一个解释器,最后偶然发现了一个我需要回溯的情况,但是我的解析器生成器(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() 但如果可以修改语法以实现同样的效果,这也对我有用
谢谢!