Comments (5)
Here you go James. It is an ANTLR v3 grammar.
If you do anything interesting with it, please share.
grammar Formula;
options
{
language=JavaScript;
output=AST;
ASTLabelType=CommonTree;
backtrack=true;
}
tokens
{
NEGATE;
ASSIGN;
FUNCALL;
MATERIAL;
UNIT;
POWER;
DEFAULTS;
PARAMS;
UNITCLUMP;
ARRAY;
LINES;
WHILE;
IFTHENELSE;
ELSE;
FOR;
FORIN;
FUNCTION;
ANONFUNCTION;
NUMBER;
LABEL;
RANGE;
INNER;
ASSIGNED;
SELECTOR;
DOTSELECTOR;
NEW;
TRYCATCH;
THROW;
}
lines
: NEWLINE* (expression (NEWLINE+|EOF))* EOF -> ^(LINES expression*)
;
NEWLINE
: ('\r'? '\n')
;
WHILESTATEMENT
: W H I L E
;
FORSTATEMENT
: F O R
;
FROMSTATEMENT
: F R O M
;
INSTATEMENT
: I N
;
TOSTATEMENT
: T O
;
BYSTATEMENT
: B Y
;
LOOPSTATEMENT
: L O O P
;
IFSTATEMENT
: I F
;
THENSTATEMENT
: T H E N
;
ELSESTATEMENT
: E L S E
;
FUNCTIONSTATEMENT
: F U N C T I O N
;
ENDBLOCK
: E N D
;
RETURNSTATEMENT
: R E T U R N
;
NEWSTATEMENT
: N E W
;
TRYSTATEMENT
: T R Y
;
CATCHSTATEMENT
: C A T C H
;
THROWSTATEMENT
: T H R O W
;
expression
: assignment
| logicalExpression
| whileLoop
| forLoop
| forInLoop
| ifThenElse
| functionDef
| returnExp
| tryCatch
| throwExp
;
returnExp
:
RETURNSTATEMENT^ logicalExpression
;
innerBlock
: (expression (NEWLINE+))* -> ^(LINES expression+)
;
whileLoop
: WHILESTATEMENT logicalExpression NEWLINE+ innerBlock ENDBLOCK LOOPSTATEMENT -> ^(WHILE logicalExpression innerBlock)
;
forLoop
: FORSTATEMENT IDENT FROMSTATEMENT logicalExpression TOSTATEMENT logicalExpression (BYSTATEMENT logicalExpression)? NEWLINE+ innerBlock ENDBLOCK LOOPSTATEMENT -> ^(FOR IDENT ^(PARAMS logicalExpression*) innerBlock)
;
forInLoop
: FORSTATEMENT IDENT INSTATEMENT logicalExpression NEWLINE+ innerBlock ENDBLOCK LOOPSTATEMENT -> ^(FORIN IDENT logicalExpression innerBlock)
;
ifThenElse
: IFSTATEMENT logicalExpression THENSTATEMENT NEWLINE+ innerBlock (ELSESTATEMENT IFSTATEMENT logicalExpression THENSTATEMENT NEWLINE+ innerBlock)* (ELSESTATEMENT NEWLINE+ innerBlock)? ENDBLOCK IFSTATEMENT -> ^(IFTHENELSE ^(PARAMS logicalExpression+) ^(PARAMS innerBlock+))
;
functionDef
: FUNCTIONSTATEMENT IDENT '(' (IDENT (EQUALS defaultValue | (',' IDENT )*) (',' IDENT EQUALS defaultValue )*)? ')' NEWLINE+ innerBlock ENDBLOCK FUNCTIONSTATEMENT -> ^(FUNCTION ^(PARAMS IDENT*) ^(DEFAULTS defaultValue*) innerBlock)
;
tryCatch
: TRYSTATEMENT NEWLINE+ innerBlock CATCHSTATEMENT IDENT NEWLINE+ innerBlock ENDBLOCK TRYSTATEMENT -> ^(TRYCATCH innerBlock* IDENT)
;
throwExp
: THROWSTATEMENT primaryExpression -> ^(THROW primaryExpression)
;
anonFunctionDef
: FUNCTIONSTATEMENT '(' (IDENT (EQUALS defaultValue | (',' IDENT )*) (',' IDENT EQUALS defaultValue )*)? ')' ( (NEWLINE+ innerBlock ENDBLOCK FUNCTIONSTATEMENT) | expression) -> ^(ANONFUNCTION ^(PARAMS IDENT*) ^(DEFAULTS defaultValue*) innerBlock? expression?)
;
assignment
:
IDENT '(' (IDENT (EQUALS defaultValue | (',' IDENT )*) (',' IDENT EQUALS defaultValue )*)? ')' '<-' logicalExpression -> ^(FUNCTION ^(PARAMS IDENT*) ^(DEFAULTS defaultValue*) logicalExpression) |
(PRIMITIVE | assigned) (',' (PRIMITIVE | assigned))* '<-' logicalExpression -> ^(ASSIGN PRIMITIVE* assigned* logicalExpression)
;
assigned
: IDENT selector? -> ^(ASSIGNED IDENT selector?)
;
logicalExpression
: booleanXORExpression (OR^ booleanXORExpression)*
;
OR : '||' | O R;
booleanXORExpression
: booleanAndExpression (XOR^ booleanAndExpression)*
;
XOR : X O R;
booleanAndExpression
: equalityExpression (AND^ equalityExpression)*
;
AND : '&&' | A N D;
equalityExpression
: relationalExpression ((EQUALS|NOTEQUALS)^ relationalExpression)*
;
EQUALS
: '=' | '==';
NOTEQUALS
: '!=' | '<>';
relationalExpression
: additiveExpression ( (LT|LTEQ|GT|GTEQ)^ additiveExpression )*
;
LT : '<';
LTEQ : '<=';
GT : '>';
GTEQ : '>=';
additiveExpression
: multiplicativeExpression ( (PLUS|MINUS)^ multiplicativeExpression )*
;
PLUS : '+';
MINUS : '-';
multiplicativeExpression
: arrayExpression ( (MULT|DIV|MOD)^ arrayExpression )*
;
MULT : '*';
DIV : '/';
MOD : '%' | M O D;
arrayExpression
: negationExpression ({ this.input.get(this.input.index()-1).getText()!=" "}? COLON { this.input.get(this.input.index()-1).getText()!=" "}? negationExpression)? ( { this.input.get(this.input.index()-1).getText()!=" "}? COLON { this.input.get(this.input.index()-1).getText()!=" "}? negationExpression)? -> ^(RANGE negationExpression*)
;
negationExpression
: MINUS powerExpression -> ^(NEGATE powerExpression) |
powerExpression
;
powerExpression
: unaryExpression (POW unaryOrNegate )* -> ^(POWER unaryExpression unaryOrNegate*)
;
unaryOrNegate
: unaryExpression |
MINUS unaryExpression -> ^(NEGATE unaryExpression)
;
POW : '^';
unaryExpression
: NOT^ innerPrimaryExpression
| innerPrimaryExpression
;
NOT : '!' | N O T;
innerPrimaryExpression
: selectionExpression -> ^(INNER selectionExpression)
;
selectionExpression
: primaryExpression ({ this.input.get(this.input.index()-1).getText()!=" "}? (selector|funCall))*
;
funCall :
'(' ( logicalExpression (',' logicalExpression)* )? ')' -> ^(FUNCALL logicalExpression*)
;
primaryExpression
: '('! logicalExpression ')'!
| value
;
value
: number
| bool
| string
| material
| IDENT
| primitive
| array
| anonFunctionDef
| newObject
;
newObject
: NEWSTATEMENT IDENT funCall? -> ^(NEW IDENT funCall?);
defaultValue
: negnumber
| number
| bool
| string
| array
;
array
:
LARR NEWLINE* (label NEWLINE* (',' NEWLINE* label NEWLINE*)*)? NEWLINE* RARR -> ^(ARRAY label*)
| LCURL NEWLINE* (label NEWLINE*(',' NEWLINE* label NEWLINE*)*)? NEWLINE* RCURL -> ^(ARRAY label*)
;
selector
: (minarray | dotselector) -> ^(SELECTOR minarray? dotselector?)
;
minarray
:
LARR! (logicalExpression|MULT) (COMMA! (logicalExpression|MULT) )* RARR!
| LCURL! (logicalExpression|MULT) (COMMA! (logicalExpression|MULT) )* RCURL!
;
dotselector
: ('.' arrayName)+ -> ^(DOTSELECTOR arrayName+)
;
arrayName
: IDENT|STRING|MULT;
label :
(arrayName NEWLINE* COLON)? NEWLINE* logicalExpression -> ^(LABEL logicalExpression arrayName?)
;
LARR : '\u00AB' | '<<' ;
RARR : '\u00BB' | '>>' ;
LCURL : '{';
RCURL : '}';
number : INTEGER|FLOAT;
negnumber : '-' number -> ^(NEGATE number);
INTEGER
: ('0'..'9')+ ('e' ('+'|'-')? ('0'..'9')* )?
;
FLOAT
: ('0'..'9')* '.' ('0'..'9')+ ('e' ('+'|'-')? ('0'..'9')* )?
;
bool
: TRUE
| FALSE
;
TRUE
: T R U E
;
FALSE
: F A L S E
;
material: LCURL additiveExpression { this.input.get(this.input.index()-1).getText()==" "}? unitMultiplicativeExpression RCURL -> ^(MATERIAL unitMultiplicativeExpression additiveExpression)
;
PER
: P E R
;
unitMultiplicativeExpression
: unitInnerMultiplicativeExpression ( PER^ unitInnerMultiplicativeExpression ) *
;
unitInnerMultiplicativeExpression
: unitClump ( (MULT|DIV)^ unitClump ) *
;
unitClump
: (INTEGER DIV) unitPowerExpression CUBED? SQUARED? -> ^(UNITCLUMP unitPowerExpression NEGATE CUBED* SQUARED*)
| unitPowerExpression CUBED? SQUARED? -> ^(UNITCLUMP unitPowerExpression CUBED* SQUARED*)
;
SQUARED : S Q U A R E D;
CUBED : C U B E D;
unitPowerExpression
: unit ( POW^ MINUS? (INTEGER|FLOAT) )*
;
unit : IDENT (IDENT)* -> ^(UNIT IDENT+)
| '(' unitMultiplicativeExpression ')' -> ^(UNITCLUMP unitMultiplicativeExpression)
;
IDENT
: ('a'..'z' | 'A'..'Z') ('a'..'z' | 'A'..'Z' | '_' | '0'..'9')*
;
primitive
: PRIMITIVE
;
PRIMITIVE
: LBRACKET (~'[') .* RBRACKET
| LBRACKET LBRACKET .* RBRACKET RBRACKET
;
LBRACKET
: '[';
RBRACKET
: ']';
COMMENT
: '/*' ( options {greedy=false;} : . )* '*/' {$channel=HIDDEN;}
;
LINE_COMMENT
: ('//'|'#') (~('\n'|'\r'))* {$channel=HIDDEN;}
;
COLON
: ':'
;
/* Ignore white spaces */
WS
: (' '|'\t'|'\u000C')+ {$channel=HIDDEN;}
;
fragment A:('a'|'A');
fragment B:('b'|'B');
fragment C:('c'|'C');
fragment D:('d'|'D');
fragment E:('e'|'E');
fragment F:('f'|'F');
fragment G:('g'|'G');
fragment H:('h'|'H');
fragment I:('i'|'I');
fragment J:('j'|'J');
fragment K:('k'|'K');
fragment L:('l'|'L');
fragment M:('m'|'M');
fragment N:('n'|'N');
fragment O:('o'|'O');
fragment P:('p'|'P');
fragment Q:('q'|'Q');
fragment R:('r'|'R');
fragment S:('s'|'S');
fragment T:('t'|'T');
fragment U:('u'|'U');
fragment V:('v'|'V');
fragment W:('w'|'W');
fragment X:('x'|'X');
fragment Y:('y'|'Y');
fragment Z:('z'|'Z');
string
: STRING^
;
COMMA
: ','
;
STRING :
'\'' .* '\''
| '"' ('\\\"'|~'\"')* '"';
from simulation.
Thank you! I look forward to experimenting with this and I'll definitely post back here with any news.
from simulation.
Related Issues (4)
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from simulation.