Improved grammar
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
|
||||
const lexer = moo.compile({
|
||||
number: /[0-9]+(?:\.[0-9]+)?/,
|
||||
string: /'.*?'|".*?"/,
|
||||
name: {match: /[a-zA-Z]+\w*?/, type: moo.keywords({
|
||||
'keywords': ['if', 'else', 'd'],
|
||||
})},
|
||||
@@ -16,15 +17,41 @@
|
||||
orOperator: ['|', '||'],
|
||||
equalityOperator: ['=', '==', '===', '!=', '!=='],
|
||||
relationalOperator: ['>', '<', '>=', '<='],
|
||||
brackets: {match: ['(', ')', '{', '}'], value: () => null},
|
||||
brackets: ['(', ')', '{', '}'],
|
||||
});
|
||||
%}
|
||||
|
||||
@{% function nuller() { return null; } %}
|
||||
|
||||
@{%
|
||||
function operator([left, _1, op, _2, right]){
|
||||
return {type: 'operation', operator: op.value, left, right};
|
||||
class OperatorNode {
|
||||
constructor({left, right, operator, fn}) {
|
||||
this.left = left;
|
||||
this.right = right;
|
||||
this.fn = fn;
|
||||
this.operator = operator;
|
||||
}
|
||||
}
|
||||
function operator([left, _1, operator, _2, right], fn){
|
||||
return new OperatorNode({
|
||||
left,
|
||||
right,
|
||||
operator: operator.value,
|
||||
fn
|
||||
});
|
||||
}
|
||||
|
||||
class SymbolNode {
|
||||
constructor(name){
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
class ConstantNode {
|
||||
constructor(value, type){
|
||||
this.value = value;
|
||||
this.type = type;
|
||||
}
|
||||
}
|
||||
%}
|
||||
|
||||
@@ -32,66 +59,73 @@
|
||||
@lexer lexer
|
||||
|
||||
ifStatement ->
|
||||
"if" _ "(" _ callExpression _ ")" _ ifStatement _ "else" _ ifStatement {% d => ({condition: d[4], true: d[8], false: d[12]}) %}
|
||||
| callExpression {% id %}
|
||||
|
||||
callExpression ->
|
||||
name _ arguments
|
||||
{%
|
||||
d => ({type: "call", function: d[0], arguments: d[2]})
|
||||
%}
|
||||
"if" _ "(" _ expression _ ")" _ ifStatement _ "else" _ ifStatement {% d => ({condition: d[4], true: d[8], false: d[12]}) %}
|
||||
| expression {% id %}
|
||||
|
||||
arguments ->
|
||||
"(" _ (expression {% d => d[0] %}):? ( _ "," _ expression {% d => d[3] %} ):* _ ")"
|
||||
{%
|
||||
d => [d[2], ...d[3]]
|
||||
%}
|
||||
|
||||
expression -> equalityExpression {% id %}
|
||||
expression ->
|
||||
equalityExpression {% d => d[0] %}
|
||||
|
||||
equalityExpression ->
|
||||
equalityExpression _ %equalityOperator _ relationalExpression {%operator%}
|
||||
equalityExpression _ %equalityOperator _ relationalExpression {% d => operator(d, 'equality') %}
|
||||
| relationalExpression {% id %}
|
||||
|
||||
relationalExpression ->
|
||||
relationalExpression _ %relationalOperator _ additiveExpression {%operator%}
|
||||
| additiveExpression {% id %}
|
||||
relationalExpression _ %relationalOperator _ orExpression {% d => operator(d, 'relation') %}
|
||||
| orExpression {% id %}
|
||||
|
||||
orExpression ->
|
||||
orExpression _ %orOperator _ andExpression {%operator%}
|
||||
orExpression _ %orOperator _ andExpression {% d => operator(d, 'or') %}
|
||||
| andExpression {% id %}
|
||||
|
||||
andExpression ->
|
||||
andExpression _ %andOperator _ equalityExpression {%operator%}
|
||||
| equalityExpression {% id %}
|
||||
andExpression _ %andOperator _ additiveExpression {% d => operator(d, 'and') %}
|
||||
| additiveExpression {% id %}
|
||||
|
||||
additiveExpression ->
|
||||
additiveExpression _ %additiveOperator _ rollExpression {%operator%}
|
||||
| rollExpression {% id %}
|
||||
|
||||
rollExpression ->
|
||||
rollExpression _ "d" _ multiplicativeExpression {% operator %}
|
||||
additiveExpression _ %additiveOperator _ multiplicativeExpression {% d => operator(d, 'add') %}
|
||||
| multiplicativeExpression {% id %}
|
||||
|
||||
multiplicativeExpression ->
|
||||
multiplicativeExpression _ %multiplicativeOperator _ exponentExpression {%operator%}
|
||||
multiplicativeExpression _ %multiplicativeOperator _ rollExpression {% d => operator(d, 'multiply') %}
|
||||
| rollExpression {% id %}
|
||||
|
||||
rollExpression ->
|
||||
rollExpression _ "d" _ exponentExpression {% d => operator(d, 'roll') %}
|
||||
| exponentExpression {% id %}
|
||||
|
||||
exponentExpression ->
|
||||
exponentExpression _ %exponentOperator _ valueExpression {%operator%}
|
||||
callExpression _ %exponentOperator _ exponentExpression {% d => operator(d, 'exponent') %}
|
||||
| callExpression {% id %}
|
||||
|
||||
callExpression ->
|
||||
name _ arguments {%
|
||||
d => ({type: "call", function: d[0], arguments: d[2]})
|
||||
%}
|
||||
| parenthesizedExpression {% id %}
|
||||
|
||||
arguments ->
|
||||
"(" _ (expression {% d => d[0] %}):? ( _ "," _ expression {% d => d[3] %} ):* _ ")" {%
|
||||
d => [d[2], ...d[3]]
|
||||
%}
|
||||
|
||||
parenthesizedExpression ->
|
||||
"(" _ expression _ ")" {% d => d[2] %}
|
||||
| valueExpression {% id %}
|
||||
|
||||
valueExpression ->
|
||||
name {% id %}
|
||||
| number {% id %}
|
||||
| string {% id %}
|
||||
|
||||
# A number or a function of a number
|
||||
number ->
|
||||
%number {% d => d[0].value %}
|
||||
%number {% d => new ConstantNode(d[0].value, 'number') %}
|
||||
|
||||
name ->
|
||||
%name {% d => d[0].value %}
|
||||
%name {% d => new SymbolNode(d[0].value) %}
|
||||
|
||||
string ->
|
||||
%string {% d => new ConstantNode(d[0].value, 'string') %}
|
||||
|
||||
_ ->
|
||||
null
|
||||
|
||||
Reference in New Issue
Block a user