如何扩展默认 PEG.js 算术示例以允许多个表达式而不是单个表达式?
How to extend default PEG.js arithmetic example to allow multiple expressions not single one?
作为我的解析器的一部分,我想添加算术和布尔表达式。我想在 https://pegjs.org/online 中使用默认的 PEG.js 示例,但问题是该解析器是递归的,你不能写两行或更多行:
例如这是有效的 JavaScript:
2 * (3 + 4)
2 * (3 + 4)
2 * (3 + 4)
+ 10
如您所见,有 3 个表达式,行尾不终止它们。但是对于 PEG.js 它们需要显式编码,因此表达式可以终止。
你会如何创建这样的无限表达式,终止并转到下一个表达式?
您可以为多个表达式添加如下所示的 Start
规则。
Start
= head:Expression tail:("\n" Expression)* {
return [head].concat(tail.map(function(element) {
return element[1];
}));
}
Expression
= head:Term tail:(_ ("+" / "-") _ Term)* {
return tail.reduce(function(result, element) {
if (element[1] === "+") { return result + element[3]; }
if (element[1] === "-") { return result - element[3]; }
}, head);
}
Term
= head:Factor tail:(_ ("*" / "/") _ Factor)* {
return tail.reduce(function(result, element) {
if (element[1] === "*") { return result * element[3]; }
if (element[1] === "/") { return result / element[3]; }
}, head);
}
Factor
= "(" _ expr:Expression _ ")" { return expr; }
/ Integer
Integer "integer"
= _ [0-9]+ { return parseInt(text(), 10); }
_ "whitespace"
= [ \t\n\r]*
作为我的解析器的一部分,我想添加算术和布尔表达式。我想在 https://pegjs.org/online 中使用默认的 PEG.js 示例,但问题是该解析器是递归的,你不能写两行或更多行:
例如这是有效的 JavaScript:
2 * (3 + 4)
2 * (3 + 4)
2 * (3 + 4)
+ 10
如您所见,有 3 个表达式,行尾不终止它们。但是对于 PEG.js 它们需要显式编码,因此表达式可以终止。
你会如何创建这样的无限表达式,终止并转到下一个表达式?
您可以为多个表达式添加如下所示的 Start
规则。
Start
= head:Expression tail:("\n" Expression)* {
return [head].concat(tail.map(function(element) {
return element[1];
}));
}
Expression
= head:Term tail:(_ ("+" / "-") _ Term)* {
return tail.reduce(function(result, element) {
if (element[1] === "+") { return result + element[3]; }
if (element[1] === "-") { return result - element[3]; }
}, head);
}
Term
= head:Factor tail:(_ ("*" / "/") _ Factor)* {
return tail.reduce(function(result, element) {
if (element[1] === "*") { return result * element[3]; }
if (element[1] === "/") { return result / element[3]; }
}, head);
}
Factor
= "(" _ expr:Expression _ ")" { return expr; }
/ Integer
Integer "integer"
= _ [0-9]+ { return parseInt(text(), 10); }
_ "whitespace"
= [ \t\n\r]*