首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Nearley.js进行分析的友好错误报告

使用Nearley.js进行分析的友好错误报告
EN

Stack Overflow用户
提问于 2019-09-18 18:49:20
回答 3查看 443关注 0票数 1

是否可以使用Nearley.js呈现用户友好的解析器错误?

代码语言:javascript
复制
const parser = new nearley.Parser((bracketexpr_grammar));
parse(): void{
    try {       
        parser.feed(this._sql);
        this._rawData = parser.results[0];
    } catch(error){
        console.log(error);
        this._errors.push(error.offset);
    }
}

我试过的是:

  • error.offset:只显示发生错误的行(不是我想要的)。
  • error:它给了我一个巨大的错误,例如:

代码语言:javascript
复制
Invalid syntax at line 1 col 1:

b4d455
^
Unexpected "b"

Instead of a "b", I was expecting to see one of the following:
    A "#" based on:
        csscolor →  ● "#" hexdigit hexdigit hexdigit hexdigit hexdigit hexdigit
    A "#" based on:
        csscolor →  ● "#" hexdigit hexdigit hexdigit
    A "r" based on:
        csscolor$string$1 →  ● "r" "g" "b"
        csscolor →  ● csscolor$string$1 _ "(" _ colnum _ "," _ colnum _ "," _ colnum _ ")"
    A "h" based on:
        csscolor$string$2 →  ● "h" "s" "l"
        csscolor →  ● csscolor$string$2 _ "(" _ colnum _ "," _ colnum _ "," _ colnum _ ")"
    A "r" based on:
        csscolor$string$3 →  ● "r" "g" "b" "a"
        csscolor →  ● csscolor$string$3 _ "(" _ colnum _ "," _ colnum _ "," _ colnum _ "," _ decimal _ ")"
    A "h" based on:
        csscolor$string$4 →  ● "h" "s" "l" "a"
        csscolor →  ● csscolor$string$4 _ "(" _ colnum _ "," _ colnum _ "," _ colnum _ "," _ decimal _ ")"

我想要的是更简单、更干净的东西,而不是那种巨大的错误:

代码语言:javascript
复制
Invalid syntax at line 1 col 1:

b4d455
^
Unexpected "b"

是可能的吗?

https://nearley.js.org/docs/parser#catching-errors

EN

回答 3

Stack Overflow用户

发布于 2019-12-29 16:48:46

此扩展的错误消息传递来自于在变更Nearley中对用户友好的错误报告功能v1所做的更改。它不显示这是当前可配置的。如果您对请求此功能感兴趣,那么打开与Nearley的问题可能是值得的。

在用这个新特性升级到版本时,我也遇到了同样的问题。作为一种解决方法,可以重写错误报告以使用先前的实现,尽管这还没有文档化,而且在升级Nearley时可能会中断。

代码语言:javascript
复制
  const parser = new Parser(...);
  // Nearley error message has been extended to show all possible correct parses.
  // As a workaround, previous implementation has been overwritten here instead.
  // When Nearley allows turning off this extended error messaging, remove this workaround.
  parser.reportError = function(token) {
    var message = this.lexer.formatError(token, 'invalid syntax') + '\n';
    message += 'Unexpected ' + (token.type ? token.type + ' token: ' : '');
    message +=
      JSON.stringify(token.value !== undefined ? token.value : token) + '\n';
    return message;
  };
票数 0
EN

Stack Overflow用户

发布于 2022-04-26 15:00:34

在Nearley的版本2.20.1中,Error对象有一个属性token,可以用来简化消息。在下面的示例中,我们使用RegExp遍历错误的message属性,并将预期的令牌添加到消息中。

RegExp基于这样的观察:在Nearley错误消息中,正如您在上面的问题中所看到的,有许多重复的A "<something>" based on:模式(对于命名令牌更改为A <something> token based on:)。

代码语言:javascript
复制
function parseFromFile(origin) {
  try {
    const parser = new nearley.Parser(nearley.Grammar.fromCompiled(grammar));
    const source = fs.readFileSync(origin, 'utf8');
    parser.feed(source);
    let results = parser.results;
    
    if (results.length > 1) throw new Error(`Language Design Error: Ambiguous Grammar! Generated ${results.length}) ASTs`);
    if (results.length ==  0) {
      console.error("Unexpected end of Input error. Incomplete Egg program. Expected more input");
      process.exit(1);
    }
    const ast = results[0];
    return ast;
  }
  catch(e) {
    let token = e.token;
    let message = e.message;
    let expected = message.match(/(?<=A ).*(?= based on:)/g).map(s => s.replace(/\s+token/i,''));
    let newMessage = `Unexpected ${token.type} token "${token.value}" `+
    `at line ${token.line} col ${token.col}.`;
    if (expected && expected.length) newMessage += ` Tokens expected: ${[...new Set(expected)]}`;  

    throw new Error(newMessage)
  }
}

当用错误的输入执行时,消息被简化为:

代码语言:javascript
复制
➜  egg-oop-parser-solution git:(master) ✗ bin/eggc.js test/errors/unexpected-token.egg
Unexpected LCB token "{" at line 1 col 2. Tokens expected: "(","[",".",EOF

与错误管理相关的另一个概念是在语法生成规则中引入特定错误情况的规则,并使用相关的语义操作来处理错误。有关更多信息,请参见此部分

票数 0
EN

Stack Overflow用户

发布于 2022-10-21 00:12:42

或者,如果使用moo.js,则对意外或未实现的令牌有内置支持。声明了lexer之后,只需将最后一个令牌添加为

代码语言:javascript
复制
{
    match: /./,
    error: true,
}

它所做的是设置任何符号或符号集,这些符号或符号集不是在特定的位置,而是将错误抛出,指向错误的位置。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57999130

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档