Last active
September 28, 2019 08:16
-
-
Save openorclose/20ed33f18d60f6474b6c3e0731cb7f7e to your computer and use it in GitHub Desktop.
grammar for Source
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* description: Parses end executes JediScript expressions. */ | |
/* lexical grammar */ | |
%lex | |
%x DoubleQuotedString | |
%x SingleQuotedString | |
%x QuotedStringEscape | |
%% | |
\/\/([^\n\r]*) /* skip single-line comments */ | |
\/\*([\u0000-\uffff]*?)\*\/ /* skip multi-line comments */ | |
\s+ /* skip whitespace */ | |
"function" return 'function' | |
"return" return 'return' | |
"if" return 'if' | |
"else" return 'else' | |
"while" return 'while' | |
"for" return 'for' | |
"break" return 'break' | |
"continue" return 'continue' | |
"let" return 'let' | |
"const" return 'const' | |
"===" return '===' | |
"=>" return '=>' | |
"=" return '=' | |
"{" return '{' | |
"}" return '}' | |
";" return ';' | |
"," return ',' | |
"true" return 'true' | |
"false" return 'false' | |
"NaN" return 'NaN' | |
"Infinity" return 'Infinity' | |
"null" return 'emptylist' | |
"[" return '[' | |
"]" return ']' | |
'""' return 'EmptyString' | |
"''" return 'EmptyString' | |
'"' this.begin('DoubleQuotedString'); | |
"'" this.begin('SingleQuotedString'); | |
<DoubleQuotedString,SingleQuotedString>\\ this.begin('QuotedStringEscape'); | |
<DoubleQuotedString>'"' this.popState(); | |
<SingleQuotedString>"'" this.popState(); | |
<QuotedStringEscape>(.|\r\n|\n) { this.popState(); return 'QuotedStringEscape'; } /* The newlines are there because we can span strings across lines using \ */ | |
<DoubleQuotedString>[^"\\]* return 'QuotedString'; | |
<SingleQuotedString>[^'\\]* return 'QuotedString'; | |
[A-Za-z_][A-Za-z0-9_]* return 'Identifier' /* TODO: non-ASCII identifiers */ | |
[0-9]+("."[0-9]+)?([eE][\-+]?[0-9]+)?\b return 'FLOAT_NUMBER' /* 3.1, 3.1e-7 */ | |
[0-9]+\b return 'INT_NUMBER' | |
"+" return '+' | |
"-" return '-' | |
"*" return '*' | |
"/" return '/' | |
"%" return '%' | |
"!==" return '!==' | |
"<=" return '<=' | |
">=" return '>=' | |
"<" return '<' | |
">" return '>' | |
"!" return '!' | |
"&&" return '&&' | |
"||" return '||' | |
"(" return '(' | |
")" return ')' | |
"?" return '?' | |
":" return ':' | |
<<EOF>> return 'EOF' | |
. return 'INVALID' | |
/lex | |
/* operator associations and precedence */ | |
%left ';' | |
%right '=' | |
%left '=>' ARROW | |
%right '?' ':' | |
%left '||' | |
%left '&&' | |
%left '===' '!==' | |
%left '<' '>' '<=' '>=' | |
%left '+' '-' | |
%left '*' '/' '%' | |
%right '!' UMINUS UPLUS | |
%left '[' ']' | |
%left '.' | |
%% /* language grammar */ | |
program | |
: statements EOF | |
{ return $1; } | |
; | |
statements | |
: | |
{ $$ = ""; } | |
| statement statements | |
{ $$ = $1 + $2; } | |
; | |
statement | |
: | |
ifstatement | |
| whilestatement | |
| forstatement | |
| 'function ' identifier '(' identifiers ')' '{' statements '}' | |
{{ | |
$$ = "function" + $2 + "(" + $4 + ") {" + $7 + "}" ; | |
}} | |
| constdeclaration | |
| letdeclaration | |
| '{' statements '}' | |
{{ | |
$$ = "{" + $2 + "}"; | |
}} | |
| assignment ';' | |
{{ | |
$$ = $1 + ";"; | |
}} | |
| expression ';' | |
{{ | |
$$ = $1 + ";"; | |
}} | |
| 'return' expression ';' | |
{{ | |
$$ = "return " + $2 + ";"; | |
}} | |
| break ';' | |
{{ | |
$$ = "break;"; | |
}} | |
| continue ';' | |
{{ | |
$$ = "continue;"; | |
}} | |
; | |
letdeclaration | |
: | |
'let' identifier '=' expression ';' | |
{{ | |
$$ = "var " + $2 + "=" + $4 + ";"; | |
}} | |
; | |
constdeclaration | |
: | |
'const' identifier '=' expression ';' | |
{{ | |
$$ = "var " + $2 + "=" + $4 + ";"; | |
}} | |
; | |
assignment | |
: | |
expression '=' expression | |
{{ | |
$$ = $1 + "=" + $3; | |
}} | |
; | |
ifstatement | |
: | |
'if' '(' expression ')' '{' statements '}' 'else' '{' statements '}' | |
{{ | |
$$ = "if (" + $3 + ") {" + $6 + "} else {" + $10 + "}"; | |
}} | |
| 'if' '(' expression ')' '{' statements '}' 'else' ifstatement | |
{{ | |
$$ = "if (" + $3 + ") {" + $6 + "} else " + $9; | |
}} | |
; | |
whilestatement | |
: | |
'while' '(' expression ')' '{' statements '}' | |
{{ | |
$$ = "while (" + $3 + ") {" + $6 + "}"; | |
}} | |
; | |
forstatement | |
: | |
'for' '(' forinitialiser expression ';' forfinaliser ')' '{' statements '}' | |
{{ | |
$$ = "for (" + $3 + $4 + ";" + $6 + ") {" + $9 + "}"; | |
}} | |
; | |
forinitialiser | |
: | |
letdeclaration | |
| assignment ';' | |
{{ | |
$$ = $1 + ";"; | |
}} | |
; | |
forfinaliser | |
: | |
assignment | |
; | |
expression | |
: | |
expression '+' expression | |
{{ | |
$$ = $1 + "+" + $3; | |
}} | |
| expression '-' expression | |
{{ | |
$$ = $1 + "-" + $3; | |
}} | |
| expression '*' expression | |
{{ | |
$$ = $1 + "*" + $3; | |
}} | |
| expression '/' expression | |
{{ | |
$$ = $1 + "/" + $3; | |
}} | |
| expression '%' expression | |
{{ | |
$$ = $1 + "%" + $3; | |
}} | |
| '-' expression %prec UMINUS | |
{{ | |
$$ = "-" + $1; | |
}} | |
| '+' expression %prec UPLUS | |
{{ | |
$$ = "+" + $1; | |
}} | |
| '!' expression | |
{{ | |
$$ = "!" + $1; | |
}} | |
| expression '&&' expression | |
{{ | |
$$ = $1 + "&&" + $3; | |
}} | |
| expression '||' expression | |
{{ | |
$$ = $1 + "||" + $3; | |
}} | |
| expression '===' expression | |
{{ | |
$$ = $1 + "===" + $3; | |
}} | |
| expression '!==' expression | |
{{ | |
$$ = $1 + "!==" + $3; | |
}} | |
| expression '>' expression | |
{{ | |
$$ = $1 + ">" + $3; | |
}} | |
| expression '<' expression | |
{{ | |
$$ = $1 + "<" + $3; | |
}} | |
| expression '>=' expression | |
{{ | |
$$ = $1 + ">=" + $3; | |
}} | |
| expression '<=' expression | |
{{ | |
$$ = $1 + "<=" + $3; | |
}} | |
| '(' identifiers ')' '=>' expression %prec ARROW | |
{{ | |
$$ = "(function(" + $2 + "){ return " + $5 + ";})"; | |
}} | |
| '(' identifiers ')' '=>' '{' statements '}' %prec ARROW | |
{{ | |
$$ = "(function(" + $2 + "){ " + $6 + "})"; | |
}} | |
| identifier '=>' expression | |
{{ | |
$$ = "(function(" + $1 + "){ return " + $3 + ";})"; | |
}} | |
| identifier '=>' '{' statements '}' | |
{{ | |
$$ = "(function(" + $1 + "){ " + $4 + "})"; | |
}} | |
| expression '[' expression ']' | |
{{ | |
$$ = $1 + "[" + $3 + "]" | |
}} | |
| '(' expression ')' | |
{$$ = "(" + $2 + ")";} | |
| constants | |
{ $$ = $1; } | |
| identifier | |
{ $$ = $1; } | |
| '(' expression ')' '(' expressions ')' | |
{{ | |
$$ = "(" + $2 + ")(" + $5 + ")"; | |
}} | |
| '[' expressions ']' | |
{{ | |
$$ = "[" + $2 + "]"; | |
}} | |
| identifier '(' expressions ')' | |
{{ | |
$$ = $1 + "(" + $3 + ")"; | |
}} | |
| expression '?' expression ':' expression | |
{{ | |
$$ = $1 + "?" + $3 + ":" + $5; | |
}} | |
; | |
constants | |
: | |
'FLOAT_NUMBER' | |
{ $$ = String(parseFloat(yytext)); } | |
| 'INT_NUMBER' | |
{ $$ = String(parseInt(yytext, 10)); } | |
| 'true' | |
{ $$ = 'true'; } | |
| 'false' | |
{ $$ = 'false'; } | |
| 'NaN' | |
{ $$ = 'NaN'; } | |
| 'Infinity' | |
{ $$ = 'Infinity'; } | |
| quotedstring | |
| 'emptylist' | |
{ $$ = 'null'; } | |
; | |
quotedstring | |
: | |
'EmptyString' | |
{ | |
$$ = '""'; | |
} | |
| 'QuotedString' | |
| 'QuotedStringEscape' | |
{ | |
switch (yytext) | |
{ | |
case 'b': $$ = '\b'; break; | |
case 'n': $$ = '\n'; break; | |
case 'r': $$ = '\r'; break; | |
case 't': $$ = '\t'; break; | |
case "'": $$ = "'"; break; | |
case '"': $$ = '"'; break; | |
case '\\': $$ = '\\'; break; | |
case '\n': | |
case '\r\n': $$ = ''; break; | |
default: $$ = '\\' + $1; break; | |
} | |
} | |
| 'QuotedStringEscape' quotedstring | |
{ | |
switch ($1) | |
{ | |
case 'b': $$ = '\b'; break; | |
case 'n': $$ = '\n'; break; | |
case 'r': $$ = '\r'; break; | |
case 't': $$ = '\t'; break; | |
case "'": $$ = "'"; break; | |
case '"': $$ = '"'; break; | |
case '\\': $$ = '\\'; break; | |
case '\n': | |
case '\r\n': $$ = ''; break; | |
default: $$ = '\\' + $1; break; | |
} | |
$$ += $2; | |
} | |
| 'QuotedString' quotedstring | |
{ | |
$$ = $1 + $2; | |
} | |
; | |
expressions | |
: | |
nonemptyexpressions | |
{ $$ = $1; } | |
| /* NOTHING */ | |
{ $$ = ""; } | |
; | |
nonemptyexpressions | |
: | |
expression ',' nonemptyexpressions | |
{ $$ = $1 + "," + $3; } | |
| expression | |
{ $$ = $1; } | |
; | |
identifiers | |
: | |
nonemptyidentifiers | |
{ $$ = $1; } | |
| /* NOTHING */ | |
{ $$ = ""; } | |
; | |
nonemptyidentifiers | |
: | |
identifier ',' nonemptyidentifiers | |
{ $$ = $1 + "," + $3; } | |
| identifier | |
{ $$ = $1; } | |
; | |
identifier | |
: | |
'Identifier' | |
{{ | |
$$ = yytext; | |
}} | |
; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment