PEG.jsを使用して、左結合演算子の AST ( Abstract Syntax Tree ) をどのように構築しますか?
インターネットで見つけた情報に基づいてコードを記述しようとしましたが、間違いを犯したようです。
私が書いたコードは、ほとんどの式に対して間違った AST を生成します。
表現
12-6-4-2*1-1
予想AST
{
"left": {
"left": {
"left": {
"left": 12,
"operator": "-",
"right": 6
},
"operator": "-",
"right": 4
},
"operator": "-",
"right": {
"left": 2,
"operator": "*",
"right": 1
}
},
"operator": "-",
"right": 1
}
生成された AST
{
"left": {
"left": {
"left": 12,
"operator": "-",
"right": 6
},
"operator": "-",
"right": 4
},
"operator": "-",
"right": {
"left": 2,
"operator": "*",
"right": {
"left": 1,
"operator": "-",
"right": 1
}
}
}
コード
{
function operator(first, rest) {
if (rest.length === 0) return first;
return { left: first, right: rest };
};
function makeOperator(left, operator, right) {
return { left: left, operator: operator[0], right: clean(right[1]) };
};
function clean(expression) {
if (!expression.right) return expression;
var result = makeOperator(expression.left, expression.right[0], expression.right[0]);
for (var counter = 1, len = expression.right.length; counter < len; counter++) {
result = makeOperator(result, expression.right[counter], expression.right[counter]);
}
return result;
};
}
Start = E
E
= expression:E1
{ return clean(expression); }
E1
= expression:E2 rest:(("+" / "-") E2)*
{ return operator(expression, rest); }
E2
= expression:Value rest:(("*" / "/") E1)*
{ return operator(expression, rest); }
Value
= Number
/ BracketedExpression
Number
= [1-9][0-9]*
{ return parseInt(text(), 10); }
BracketedExpression
= "(" expression:E1 ")"
{ return expression; }
左結合演算子と右結合演算子の両方の AST を構築する方法について、ヘルプやサンプル コードをいただければ幸いです。
編集: @Bergi が指摘したように、問題は、の代わりに残りの演算子リストの式としてE2
使用されることでした。しかし、Bergi が書いたコードは私のものよりずっと単純です。E1
Value