问题描述
作为解析器的一部分,我想添加算术和布尔表达式。我想在 https://pegjs.org/online 处采用默认的 PEG.js 示例,但问题是该解析器是递归的,您不能编写两行或更多行:
例如这是有效的 JavaScript:
<!DOCTYPE html>
<html lang="en">
<head>
<Meta charset="UTF-8">
<Meta http-equiv="X-UA-Compatible" content="IE=edge">
<link rel="stylesheet" href="./style.css">
<Meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Document</title>
</head>
<body>
<main>
<div class="img">
<div class="title title-dark">MEN STARVE FOR HOnor</div>
</div>
<div class="title">MEN STARVE FOR HOnor</div>
</main>
</body>
<script src="./index.js"></script>
</html>
如您所见,有 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]*