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

在JavaScript的Peggy语法中集成Lexer Token的问题

解决Peggy语法中使用Moo Token的栈溢出与语法错误问题

核心问题分析

  1. 栈溢出原因:规则名与Moo定义的token类型重名,导致Peggy递归调用规则而非匹配token,引发无限循环。例如identifier = $identifier中,规则identifier和token类型identifier同名,Peggy会不断调用规则本身,最终栈溢出。
  2. 语法错误原因:Peggy动作代码块中返回对象时未使用return关键字,直接写{ type: ... }会被解析为代码块而非返回值,导致语法错误。

修正方案

步骤1:调整Peggy语法文件

修改grammar.peggy,避免规则名与token类型重名,并正确使用动作代码返回结果:

start
  = sentence

sentence
  = action:$action _ object:$object
    { 
      return {
        action: { type: "action", value: action },
        object: { type: "object", value: object }
      };
    }

_ "whitespace"
  = [ \t\n\r]*

步骤2:优化Moo Lexer(可选)

为避免匹配到包含目标词汇的长单词,给正则添加单词边界\b,确保只匹配完整的动作或对象词汇:

let lexer = moo.compile({
  object: {
    match: new RegExp(`\\b(${objects.join('|')})\\b`),
    type: 'object',
  },
  identifier: {
    match: /[a-z]+/,
    type: moo.keywords({
      action: actions,
    }),
  },
  and: {
    match: new RegExp(`\\b(${andOperator.join('|')})\\b`),
  },
  or: {
    match: new RegExp(`\\b(${orOperator.join('|')})\\b`),
  },
  whitespace: {match: /\s+/, lineBreaks: true},
});

步骤3:重新生成并测试

  1. 用Peggy CLI重新生成解析器:
peggy grammar.peggy -o parser.js
  1. 运行测试脚本:
node test.js

此时输入take book会输出结构化的解析结果:

{
  action: { type: 'action', value: 'take' },
  object: { type: 'object', value: 'book' }
}

关键知识点说明

  • 在Peggy中,使用$<token类型>语法直接匹配Moo生成的对应类型token,无需定义同名规则。
  • 动作代码块中返回值必须显式使用return,否则对象字面量会被解析为代码块结构,导致语法错误。
  • Moo的keywords会将匹配到的关键词标记为指定token类型,因此actions数组中的词汇会被识别为action类型token,而非普通identifier。

内容的提问来源于stack exchange,提问作者Suppenterrine

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 21:34:54