【问题标题】:PEGJS: How to pass a grammarPEGJS:如何通过语法
【发布时间】:2019-12-23 08:21:17
【问题描述】:

引用PEGJS Tutorial:

要生成解析器,请调用 PEG.buildParser 方法并 将您的语法作为参数传递:

var parser = PEG.buildParser("start = ('a' / 'b')+");

我的语法有点复杂:

start
  = additive

additive
  = left:multiplicative "+" right:additive { return left + right; }
  / multiplicative

multiplicative
  = left:primary "*" right:multiplicative { return left * right; }
  / primary

primary
  = integer
  / "(" additive:additive ")" { return additive; }

integer "integer"
  = digits:[0-9]+ { return parseInt(digits.join(""), 10); }

我应该将我的语法的起始规则传递给PEG.buildParser,即additive,但我做错了。 如果我写 PEG.buildParser(additive)PEG.buildParser(start),FireBug 说 SyntaxError: Expected "=" or string but end of input found; 如果我写PEG.buildParser(start = additive),我会得到GrammarError: Referenced rule "additive" does not exist; 通过语法的正确方法是什么?

【问题讨论】:

    标签: javascript parsing pegjs


    【解决方案1】:

    完整的语法必须解析为buildParser作为字符串,例如

    PEG = require('pegjs');
    var parser = PEG.buildParser(
      'start\n' +
      '  = additive\n' +
      '\n' +
      'additive\n' +
      '  = left:multiplicative "+" right:additive { return left + right; }\n' +
      '  / multiplicative\n' +
      '\n' +
      'multiplicative\n' +
      '  = left:primary "*" right:multiplicative { return left * right; }\n' +
      '  / primary\n' +
      '\n' +
      'primary\n' +
      '  = integer\n' +
      '  / "(" additive:additive ")" { return additive; }\n' +
      '\n' +
      'integer "integer"\n' +
      '  = digits:[0-9]+ { return parseInt(digits.join(""), 10); }'
    );
    console.log(parser.parse('(1+2)*3'));
    

    【讨论】:

    • 谢谢冈瑟。只是一个疑问:有没有更简单的方法来通过语法?不是字符串,可能包含外部文件?
    • @elmazzun 您的问题表明您对 Javascript API 感兴趣 - 您必须在其中传递一个字符串。只需将文件内容读入一个变量,然后传递它。否则从命令行调用 pegjs。
    • PEG.js自己的online tool可以为你生成js文件。
    【解决方案2】:

    如果您想从文件加载语法并将解析器导出到文件,请尝试此示例

    const peg = require('pegjs');
    const fs = require('fs');
    
    const grammarAsString = fs.readFileSync('./grammar.pegjs').toString();
    
    const option = {
      output: 'source',
    };
    
    const parserSourceCode = peg.generate(grammarAsString, option);
    fs.writeFileSync('./parser.js', parserSourceCode);
    
    const parser = required('./parser.js');
    const output = parser.parse("(1 + 2) * 3"); // output = 9
    
    

    如果您希望您的解析器成为对象并直接使用它将输出值从“源”更改为“解析器”,或者根本不传递它,默认为解析器。

    const peg = require('pegjs');
    const fs = require('fs');
    
    const grammarAsString = fs.readFileSync('./grammar.pegjs').toString();
    
    const parserObjet = peg.generate(grammarAsString);
    const output = parserObject.parse("(1 + 2) * 3"); // output = 9
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-12
      • 1970-01-01
      • 2017-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多