Jison EBNF语法问题求助:Kleene星无法识别多语句
嘿,我刚看完你的问题,作为Jison新手遇到这种Kleene星*不生效的情况太正常了——大概率是语法规则里的几个常见小坑没踩对,咱们一步步来解决:
核心问题分析
你定义的INSTR : INSTRUCCION*理论上确实应该支持0到多条语句,但报错说只能识别单条,最可能的原因有两个:
- 语句之间没有明确的分隔符:Jison的LR解析器不会自动推断语句边界,如果你写了
a=1b=2,它根本分不清这是两个赋值语句还是一个错误的语法。 - 语法规则的匹配逻辑有歧义:比如
INSTRUCCION的定义不够明确,或者词法规则缺失关键元素(比如分号、表达式的基础规则)。
修正后的简化语法示例
我把你的语法补全并调整了关键部分,你可以直接参考:
词法规则(%lex部分,你可能之前没写全)
%lex %% \s+ /* 跳过空白字符 */ void return 'void' if return 'IF' [a-zA-Z_][a-zA-Z0-9_]* return 'id' [0-9]+ return 'NUMBER' \( return '(' \) return ')' \{ return '{' \} return '}' = return '=' ; return ';' <<EOF>> return 'EOF' . return 'INVALID' %lex
语法规则(%%部分)
%start METODO %% METODO : 'void' id '(' ')' '{' INSTR '}' EOF ; INSTR : INSTRUCCION* ; INSTRUCCION : IF_STMT | ASSIGN_STMT ; IF_STMT : 'IF' '(' expr ')' '{' INSTR '}' ; ASSIGN_STMT : id '=' expr ';' ; // 简化的表达式规则,你可以根据需求扩展(比如加减乘除) expr : id | NUMBER ;
关键调整说明
- 添加了语句分隔符
;:在赋值语句ASSIGN_STMT里明确要求分号结尾,这样解析器能清晰区分每个语句的边界。 - 补全了词法规则:加入了数字
NUMBER和基础的表达式规则expr,避免因为表达式无法解析导致语句匹配失败。 - 入口规则加上
EOF:确保解析器会检查整个输入是否完全匹配,不会中途停止。 - 拆分了
INSTRUCCION的子规则:把IF和赋值语句拆成IF_STMT和ASSIGN_STMT,让规则更清晰,减少歧义。
测试用例
你可以用这段输入测试修正后的语法:
void test() { x = 10; if (y) { z = 20; } }
它应该能正确识别外层的2条语句,以及if块里的1条语句。
如果还是有问题,你可以补充下具体的报错信息和测试输入,我再帮你排查~
内容的提问来源于stack exchange,提问作者Marilu
相关产品推荐
相关产品推荐

