diff --git a/app/imports/parser/grammar.js b/app/imports/parser/grammar.js index 4d0b0a78..8e29fb16 100644 --- a/app/imports/parser/grammar.js +++ b/app/imports/parser/grammar.js @@ -41,6 +41,7 @@ function id(x) { return x[0]; } multiplicativeOperator: ['*', '/'], exponentOperator: ['^'], additiveOperator: ['+', '-'], + moduloOperator: ['%'], andOperator: ['&', '&&'], orOperator: ['|', '||'], stringDelimiters: ['\"', '\''], @@ -75,8 +76,10 @@ let ParserRules = [ {"name": "equalityExpression", "symbols": ["relationalExpression"], "postprocess": id}, {"name": "relationalExpression", "symbols": ["relationalExpression", "_", (lexer.has("relationalOperator") ? {type: "relationalOperator"} : relationalOperator), "_", "additiveExpression"], "postprocess": d => operator(d, 'relation')}, {"name": "relationalExpression", "symbols": ["additiveExpression"], "postprocess": id}, - {"name": "additiveExpression", "symbols": ["additiveExpression", "_", (lexer.has("additiveOperator") ? {type: "additiveOperator"} : additiveOperator), "_", "multiplicativeExpression"], "postprocess": d => operator(d, 'add')}, - {"name": "additiveExpression", "symbols": ["multiplicativeExpression"], "postprocess": id}, + {"name": "additiveExpression", "symbols": ["additiveExpression", "_", (lexer.has("additiveOperator") ? {type: "additiveOperator"} : additiveOperator), "_", "remainderExpression"], "postprocess": d => operator(d, 'add')}, + {"name": "additiveExpression", "symbols": ["remainderExpression"], "postprocess": id}, + {"name": "remainderExpression", "symbols": ["remainderExpression", "_", (lexer.has("moduloOperator") ? {type: "moduloOperator"} : moduloOperator), "_", "multiplicativeExpression"], "postprocess": d => operator(d, 'remainder')}, + {"name": "remainderExpression", "symbols": ["multiplicativeExpression"], "postprocess": id}, {"name": "multiplicativeExpression", "symbols": ["multiplicativeExpression", "_", (lexer.has("multiplicativeOperator") ? {type: "multiplicativeOperator"} : multiplicativeOperator), "_", "rollExpression"], "postprocess": d => operator(d, 'multiply')}, {"name": "multiplicativeExpression", "symbols": ["rollExpression"], "postprocess": id}, {"name": "rollExpression", "symbols": ["rollExpression", "_", (lexer.has("diceOperator") ? {type: "diceOperator"} : diceOperator), "_", "exponentExpression"], "postprocess": d => new RollNode({left: d[0], right: d[4]})}, @@ -116,11 +119,14 @@ let ParserRules = [ {"name": "arrayExpression", "symbols": ["parenthesizedExpression"], "postprocess": id}, {"name": "parenthesizedExpression", "symbols": [{"literal":"("}, "_", "expression", "_", {"literal":")"}], "postprocess": d => new ParenthesisNode({content: d[2]})}, {"name": "parenthesizedExpression", "symbols": ["accessorExpression"], "postprocess": id}, - {"name": "accessorExpression$ebnf$1$subexpression$1", "symbols": [{"literal":"."}, "name"], "postprocess": d => d[1].name}, + {"name": "accessorExpression$subexpression$1", "symbols": [(lexer.has("name") ? {type: "name"} : name)], "postprocess": d => d[0].value}, + {"name": "accessorExpression$ebnf$1$subexpression$1", "symbols": [{"literal":"."}, (lexer.has("name") ? {type: "name"} : name)], "postprocess": d => d[1].value}, {"name": "accessorExpression$ebnf$1", "symbols": ["accessorExpression$ebnf$1$subexpression$1"]}, - {"name": "accessorExpression$ebnf$1$subexpression$2", "symbols": [{"literal":"."}, "name"], "postprocess": d => d[1].name}, + {"name": "accessorExpression$ebnf$1$subexpression$2", "symbols": [{"literal":"."}, (lexer.has("name") ? {type: "name"} : name)], "postprocess": d => d[1].value}, {"name": "accessorExpression$ebnf$1", "symbols": ["accessorExpression$ebnf$1", "accessorExpression$ebnf$1$subexpression$2"], "postprocess": function arrpush(d) {return d[0].concat([d[1]]);}}, - {"name": "accessorExpression", "symbols": ["name", "accessorExpression$ebnf$1"], "postprocess": d=> new AccessorNode({name: d[0], path: d[1]})}, + {"name": "accessorExpression", "symbols": ["accessorExpression$subexpression$1", "accessorExpression$ebnf$1"], "postprocess": + d=> new AccessorNode({name: d[0], path: d[1]}) + }, {"name": "accessorExpression", "symbols": ["valueExpression"], "postprocess": id}, {"name": "valueExpression", "symbols": ["name"], "postprocess": id}, {"name": "valueExpression", "symbols": ["number"], "postprocess": id}, diff --git a/app/imports/parser/grammar.ne b/app/imports/parser/grammar.ne index 5f9016be..cd278bab 100644 --- a/app/imports/parser/grammar.ne +++ b/app/imports/parser/grammar.ne @@ -39,6 +39,7 @@ multiplicativeOperator: ['*', '/'], exponentOperator: ['^'], additiveOperator: ['+', '-'], + moduloOperator: ['%'], andOperator: ['&', '&&'], orOperator: ['|', '||'], stringDelimiters: ['\"', '\''], @@ -91,7 +92,11 @@ relationalExpression -> | additiveExpression {% id %} additiveExpression -> - additiveExpression _ %additiveOperator _ multiplicativeExpression {% d => operator(d, 'add') %} + additiveExpression _ %additiveOperator _ remainderExpression {% d => operator(d, 'add') %} +| remainderExpression {% id %} + +remainderExpression -> + remainderExpression _ %moduloOperator _ multiplicativeExpression {% d => operator(d, 'remainder') %} | multiplicativeExpression {% id %} multiplicativeExpression -> @@ -144,7 +149,9 @@ parenthesizedExpression -> | accessorExpression {% id %} accessorExpression -> - name ( "." name {% d => d[1].name %} ):+ {% d=> new AccessorNode({name: d[0], path: d[1]}) %} + (%name {% d => d[0].value %}) ( "." %name {% d => d[1].value %} ):+ {% + d=> new AccessorNode({name: d[0], path: d[1]}) + %} | valueExpression {% id %} valueExpression -> diff --git a/app/imports/parser/parseTree/OperatorNode.js b/app/imports/parser/parseTree/OperatorNode.js index e6822abf..6fe63428 100644 --- a/app/imports/parser/parseTree/OperatorNode.js +++ b/app/imports/parser/parseTree/OperatorNode.js @@ -31,6 +31,7 @@ export default class OperatorNode extends ParseNode { case '*': result = left * right; break; case '/': result = left / right; break; case '^': result = Math.pow(left, right); break; + case '%': result = left % right; break; case '&': case '&&': result = left && right; break; case '|':