Skip to content

Instantly share code, notes, and snippets.

@belen-albeza
Created October 5, 2015 15:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save belen-albeza/d0c0e0d9668565958cd2 to your computer and use it in GitHub Desktop.
Save belen-albeza/d0c0e0d9668565958cd2 to your computer and use it in GitHub Desktop.
grammar.y
# esto es un ejemplo
PROGRAM lorem
BEGIN
END
/*
Heavily inspired by div2js grammar at
https://github.com/lodr/div2js/blob/master/src/grammar.y
*/
%{
function parseNumber(value) {
if (Math.floor(value) === value) { // int
return parseInt(value, 10);
}
else { // float
return parseFloat(value, 10);
}
}
%}
%lex
%options case-insensitive
ALPHA [a-zñç]
DIGIT [0-9]
NAME [a-zñç_][0-9a-zñç_]*
QUOTE [\"]
%x xcomment
%%
'#' { this.begin('xcomment'); }
<xcomment>[\n\r] { this.popState(); }
<xcomment>[^\n\r]* { return 'EOL'; }
[\n\r] { return 'EOL'; }
\s+ { /* ignore whitespace */ }
'BEGIN' { return 'BEGIN'; }
'END' { return 'END'; }
'GLOBAL' { return 'GLOBAL'; }
'null' { return 'NULL'; }
'PROGRAM' { return 'PROGRAM'; }
',' { return ','; }
'(' { return '('; }
')' { return ')'; }
'=' { return '='; }
{NAME} { return 'NAME'; }
<<EOF>> { return 'EOF'; }
{QUOTE}.*{QUOTE} { return 'STRING_LITERAL'; }
{DIGIT}+(\.{DIGIT}+)? { return 'NUMBER'}
/lex
%start program_unit
%%
program_unit
: program EOF
{
$$ = {
type: 'Unit',
program: $1
};
return $$;
}
;
program
: PROGRAM id EOL body
{
$$ = {
type: 'Program',
name: $2,
body: $4
};
}
;
id
: NAME
{
$$ = {
type: 'Identifier',
name: $1
};
}
;
body
: BEGIN EOL END EOL
{
$$ = {
type: 'Body',
sentences: []
};
}
| BEGIN EOL sentence_list END EOL
{
$$ = {
type: 'Body',
sentences: $3
};
}
;
sentence_list
: sentence
{
$$ = [$1];
}
| sentence_list sentence
{
$1.push($2);
$$ = $1;
}
;
sentence
: expression EOL
{
$$ = {
type: 'ExpressionSentence',
expression: $1
};
}
;
expression
: atomic_expression
| assignment_expression
| call_expression
;
expression_list
: expression
{
$$ = [$1];
}
| expression_list ',' expression
{
$1.push($3);
$$ = $1;
}
;
atomic_expression
: id
| NULL
{
$$ = {
type: 'Literal',
value: null
};
}
| NUMBER
{
$$ = {
type: 'Literal',
value: parseNumber($1)
};
}
| STRING_LITERAL
{
$$ = {
type: 'Literal',
value: JSON.parse($1)
};
}
;
call_expression
: NAME '(' ')'
{
$$ = {
type: 'CallExpression',
callee: $1,
args: []
};
}
| NAME '(' expression_list ')'
{
$$ = {
type: 'CallExpression',
callee: $1,
args: $3
};
}
;
assignment_expression
: id '=' expression
{
$$ = {
type: 'AssignmentExpression',
operator: $2,
left: $1,
right: $3
}
}
;
%%
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment