Tatsu语法解析故障:无法识别assign与application模式求助
Tatsu语法解析错误排查:assign与application表达式无法识别
问题重现
使用Tatsu实现miniML语法,编译通过后解析x=3;x+1时出现如下错误:
FailedExpectingEndOfText: (1:2) Expecting end of text : x=3;x+1 ^ start
同时expression expression形式的函数应用也无法被识别。原语法代码如下:
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 ')' ; """
错误原因分析
Start规则局限性
原start规则定义为expression $,要求输入必须是单个expression后立即结束。但x=3;x+1包含分号分隔的两个表达式,且原assign规则错误地将varname '=' expression ';' expression作为一个表达式,导致Tatsu匹配到x(varname分支)后就认为完成了expression匹配,期望输入结束,从而报错。Expression分支顺序错误
Tatsu对备选分支按顺序匹配,原expression将varname、integer等简单分支放在assign、application之前。当解析x=3时,Tatsu会优先匹配varname分支,不会尝试后续的assign分支,导致赋值表达式无法被识别。Application规则写法错误
原application = ' '<{expression}+不符合miniML函数应用的语法逻辑(函数后跟参数,如f x),且Tatsu语法中<{...}+的写法不正确,无法匹配表达式相邻的情况。算术运算规则设计缺陷
原加法、减法等规则仅能匹配+ (a,b)这类带括号的形式,无法处理常规的a + b表达式,也会影响整体解析逻辑。
修复后的语法示例
grammar=""" @@grammar::CALC // 支持多语句,用;分隔,最后一个语句可省略; start = statements $ ; // 语句序列定义 statements = {statement ';'}+ statement? ; // 单个语句可以是赋值或表达式 statement = assign | expression ; // 调整分支顺序:复杂结构优先,避免简单分支抢占匹配 expression = | function | application | addition | soustraction | multiplication | division | Fst | Snd | pair | varname | integer | parentheses ; integer = /\d+/ ; // 修正算术运算规则,支持常规a op b形式 addition = left:expression '+' right:expression ; soustraction = left:expression '-' right:expression ; multiplication = left:expression '*' right:expression ; division = left:expression '/' right:expression ; // 修正Fst/Snd规则,支持任意表达式参数 Fst = 'Fst' expression ; Snd = 'Snd' expression ; pair = '(' expression ',' expression ')' ; varname = /[a-z]+/ ; // 赋值作为独立语句,不再包含后续的; expression assign = varname '=' expression ; function = 'Lambda' varname ':' expression ; // 函数应用:表达式后跟另一个表达式(函数+参数) application = expression expression ; parentheses = '(' expression ')' ; """
修复说明
- Start与语句结构:新增
statements和statement规则,支持分号分隔的多语句输入,将赋值作为独立语句而非表达式的一部分,更符合miniML的语法逻辑。 - Expression分支顺序:将
function、application等复杂分支放在前面,确保Tatsu优先尝试匹配结构更复杂的语法。 - Application规则修正:改为
expression expression,正确匹配miniML中函数后跟参数的应用形式。 - 算术运算规则修正:调整为
left:expression op right:expression,支持常规的二元运算表达式。
内容的提问来源于stack exchange,提问作者Lara
相关产品推荐
相关产品推荐

