使用Jison将命令列表转为对象数组时仅返回首个对象求助
解决Jison解析器只返回第一条语句的问题
嘿,我之前也碰到过Jison里这种只返回第一条语句的问题,其实核心就是没处理语句列表的累积——你的语法规则大概率只定义了单个语句的解析,没告诉Jison要把多个语句收集成数组。咱们一步步来解决:
1. 调整核心语法规则
问题出在顶层规则和语句列表的定义上。你需要明确告诉Jison如何把多个语句组合成数组:
%start start %% start : statement_list { return $1; } // 直接返回收集到的语句数组 ; // 定义语句列表:要么是单个语句,要么是已有列表加上新语句 statement_list : statement { $$ = [$1]; } // 单个语句初始化数组 | statement_list statement { $$ = $1.concat($2); } // 把新语句追加到已有数组末尾 ; // 单个语句的解析规则(根据你的需求调整) statement : FUNC ARG { $$ = { func: $1, arg: Number($2) }; } // 生成单个语句对象,arg转成数字 ;
2. 完善词法分析与语句分隔
如果你的命令是用换行、分号这类符号分隔的,还要在词法规则里定义分隔符,并在语法里兼容它:
%lex %% \w+ return 'FUNC'; // 匹配函数名 \d+ return 'ARG'; // 匹配数字参数 [\n;] return 'SEP'; // 匹配语句分隔符(换行或分号) \s+ skip(); // 忽略空白字符 . skip(); // 跳过其他无关字符 /lex
然后更新statement规则,允许后面跟着可选的分隔符:
statement : FUNC ARG SEP? { $$ = { func: $1, arg: Number($2) }; } ;
3. 测试验证
比如输入以下命令:
foo 10 bar 20 baz 30
此时解析器应该返回预期的对象数组:
[ { func: 'foo', arg: 10 }, { func: 'bar', arg: 20 }, { func: 'baz', arg: 30 } ]
关键注意点
- 语义值的传递:
$$代表当前规则的输出结果,$1、$2是对应子规则的结果,一定要确保在statement_list的第二个分支里是追加而非覆盖数组。 - 如果你的命令有更复杂的结构(比如带括号的参数),只需要扩展
statement规则即可,核心的数组收集逻辑不变。
内容的提问来源于stack exchange,提问作者AndyPerlitch
相关产品推荐
相关产品推荐

