我正在开始使用tatsu,我正试图实现miniML语言的语法。一旦我的语法被成功解析,我就会尝试解析一些小表达式来检查它是否正常工作;然而,我发现Tatsu无法识别一些预期的模式。
代码如下:
grammar="""
@@grammar::CALC
start
=
expression $
;
expression
=
|integer
|addition
|soustraction
|multiplication
|division
|Fst
|Snd
|pair
|varname
|assign
|function
|application
|parentheses
;
integer
=
/d+/
;
addition
=
left:'+' right:pair
;
soustraction
=
'-' pair
;
multiplication
=
'*' pair
;
division
=
'/' pair
;
Fst
=
'Fst' pair
;
Snd
=
'Snd' pair
;
pair
=
'(' expression ',' expression ')'
;
varname
=
/[a-z]+/
;
assign
=
varname '=' expression ';' expression
;
function
=
'Lambda' varname ':' expression
;
application
=
' '<{expression}+
;
parentheses
=
'(' expression ')'
;
"""
然后解析:
parser = tatsu.compile(grammar)
所有这些表达式都被成功识别,除了"赋值";以及"应用"的人。如果我尝试这样做:
parser.parse("x=3;x+1")
我得到错误信息:
FailedExpectingEndOfText: (1:2) Expecting end of text :
x=3;x+1
^
start
类型的表达式也一样。我在这里犯了什么语法错误?我不知道,在文档中也找不到。
提前感谢!
assign
的失败似乎来自于与varname
规则的冲突;要解决这个问题,只需在expression
规则中将|assign
置于|variable
之前。
一个现在已经过时的解决方法,无论如何我都会留下:
# I added a negative lookahead for '=' so it will not conflict with the assign rule
varname = /[a-z]+/!'=' ;
assign = /[a-z]+/ '=' expression ';' expression ;
的例子:
parser.parse("x=1;+(x,1)")
# ['x', '=', '1', ';', AST({'left': '+', 'right': ['(', 'x', ',', '1', ')']})]
- 关于"应用程序":将
' '
替换为/ /
,并将|application
放在expression
规则的开头,解决了问题:
parser.parse("1 2 (x=1;3) *(4,5)")
Out[207]:
(' ',
'1',
(' ',
'2',
(' ',
['(', ['x', '=', '1', ';', '3'], ')'],
['*', ['(', '4', ',', '5', ')']])))