You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 03:29:48