Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/zaach/ebnf-parser
A parser for BNF and EBNF grammars used by jison
https://github.com/zaach/ebnf-parser
Last synced: 2 days ago
JSON representation
A parser for BNF and EBNF grammars used by jison
- Host: GitHub
- URL: https://github.com/zaach/ebnf-parser
- Owner: zaach
- Created: 2012-08-30T07:34:32.000Z (over 12 years ago)
- Default Branch: master
- Last Pushed: 2020-05-18T10:48:11.000Z (over 4 years ago)
- Last Synced: 2024-12-17T03:11:40.975Z (10 days ago)
- Language: JavaScript
- Size: 257 KB
- Stars: 81
- Watchers: 5
- Forks: 18
- Open Issues: 9
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# ebnf-parser
A parser for BNF and EBNF grammars used by jison.
## install
npm install ebnf-parser
## build
To build the parser yourself, clone the git repo then run:
make
This will generate `parser.js`, which is required by `ebnf-parser.js`.
## usage
The parser translates a string grammar or JSON grammar into a JSON grammar that jison can use (ENBF is transformed into BNF).
var ebnfParser = require('ebnf-parser');
// parse a bnf or ebnf string grammar
ebnfParser.parse("%start ... %");// transform an ebnf JSON gramamr
ebnfParser.transform({"ebnf": ...});## example grammar
The parser can parse its own BNF grammar, shown below:
%start spec
/* grammar for parsing jison grammar files */
%{
var transform = require('./ebnf-transform').transform;
var ebnf = false;
%}%%
spec
: declaration_list '%%' grammar optional_end_block EOF
{$$ = $1; return extend($$, $3);}
| declaration_list '%%' grammar '%%' CODE EOF
{$$ = $1; yy.addDeclaration($$,{include:$5}); return extend($$, $3);}
;optional_end_block
:
| '%%'
;declaration_list
: declaration_list declaration
{$$ = $1; yy.addDeclaration($$, $2);}
|
{$$ = {};}
;declaration
: START id
{$$ = {start: $2};}
| LEX_BLOCK
{$$ = {lex: $1};}
| operator
{$$ = {operator: $1};}
| ACTION
{$$ = {include: $1};}
;operator
: associativity token_list
{$$ = [$1]; $$.push.apply($$, $2);}
;associativity
: LEFT
{$$ = 'left';}
| RIGHT
{$$ = 'right';}
| NONASSOC
{$$ = 'nonassoc';}
;token_list
: token_list symbol
{$$ = $1; $$.push($2);}
| symbol
{$$ = [$1];}
;grammar
: production_list
{$$ = $1;}
;production_list
: production_list production
{$$ = $1;
if($2[0] in $$) $$[$2[0]] = $$[$2[0]].concat($2[1]);
else $$[$2[0]] = $2[1];}
| production
{$$ = {}; $$[$1[0]] = $1[1];}
;production
: id ':' handle_list ';'
{$$ = [$1, $3];}
;handle_list
: handle_list '|' handle_action
{$$ = $1; $$.push($3);}
| handle_action
{$$ = [$1];}
;handle_action
: handle prec action
{$$ = [($1.length ? $1.join(' ') : '')];
if($3) $$.push($3);
if($2) $$.push($2);
if ($$.length === 1) $$ = $$[0];
}
;handle
: handle expression_suffix
{$$ = $1; $$.push($2)}
|
{$$ = [];}
;handle_sublist
: handle_sublist '|' handle
{$$ = $1; $$.push($3.join(' '));}
| handle
{$$ = [$1.join(' ')];}
;expression_suffix
: expression suffix
{$$ = $expression + $suffix; }
;expression
: ID
{$$ = $1; }
| STRING
{$$ = ebnf ? "'"+$1+"'" : $1; }
| '(' handle_sublist ')'
{$$ = '(' + $handle_sublist.join(' | ') + ')'; }
;suffix
: {$$ = ''}
| '*'
| '?'
| '+'
;prec
: PREC symbol
{$$ = {prec: $2};}
|
{$$ = null;}
;symbol
: id
{$$ = $1;}
| STRING
{$$ = yytext;}
;id
: ID
{$$ = yytext;}
;action
: '{' action_body '}'
{$$ = $2;}
| ACTION
{$$ = $1;}
| ARROW_ACTION
{$$ = '$$ ='+$1+';';}
|
{$$ = '';}
;action_body
:
{$$ = '';}
| ACTION_BODY
{$$ = yytext;}
| action_body '{' action_body '}' ACTION_BODY
{$$ = $1+$2+$3+$4+$5;}
| action_body '{' action_body '}'
{$$ = $1+$2+$3+$4;}
;%%
// transform ebnf to bnf if necessary
function extend (json, grammar) {
json.bnf = ebnf ? transform(grammar) : grammar;
return json;
}## license
MIT