是否可以使用Nearley.js呈现用户友好的解析器错误?
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:它给了我一个巨大的错误,例如:。
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 _ ")"我想要的是更简单、更干净的东西,而不是那种巨大的错误:
Invalid syntax at line 1 col 1:
b4d455
^
Unexpected "b"是可能的吗?
发布于 2019-12-29 16:48:46
此扩展的错误消息传递来自于在变更Nearley中对用户友好的错误报告功能v1所做的更改。它不显示这是当前可配置的。如果您对请求此功能感兴趣,那么打开与Nearley的问题可能是值得的。
在用这个新特性升级到版本时,我也遇到了同样的问题。作为一种解决方法,可以重写错误报告以使用先前的实现,尽管这还没有文档化,而且在升级Nearley时可能会中断。
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;
};发布于 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:)。
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)
}
}当用错误的输入执行时,消息被简化为:
➜ 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与错误管理相关的另一个概念是在语法生成规则中引入特定错误情况的规则,并使用相关的语义操作来处理错误。有关更多信息,请参见此部分
发布于 2022-10-21 00:12:42
或者,如果使用moo.js,则对意外或未实现的令牌有内置支持。声明了lexer之后,只需将最后一个令牌添加为
{
match: /./,
error: true,
}它所做的是设置任何符号或符号集,这些符号或符号集不是在特定的位置,而是将错误抛出,指向错误的位置。
https://stackoverflow.com/questions/57999130
复制相似问题