This is a fork of Zach Carter zach@carter.name's jison module tweaked to use just enough templates to make typescript compilers tollerate the generated parser. This works (I'm using it in a few javascript and typescript projects) and runs all of the original tests except the ones that generated AMD and CommonJS packages. If you want to geek about this, ping ericP on discord or ericprud on gitter.
Four previously-independent projects have been placed in this mono-repo:
old npm pakage | new npm package | monorepo directory |
---|---|---|
jison | @ts-jison/parser-generator | packages/parser-generator |
jison-lex | @ts-jison/lexer-generator | packages/lexer-generator |
ebnf-parser | @ts-jison/ebnf-parser | packages/ebnf-parser |
lex-parser | @ts-jison/lex-parser | packages/lex-parser |
In addition, the parser and lexer have been factored following DRY principles but mostly to enable coverage tests on parsers (an excellent way to govern test suite coverage of language features). This results in a smaller footprint for projects that include more than on parser.
new npm package | monorepo directory |
---|---|
@ts-jison/parser | packages/parser |
@ts-jison/lexer | packages/lexer |
@ts-jison/common | packages/common |
@ts-jison/common-generator | packages/common-generator |
This example parses and executes mathematical expressions:
%{
function hexlify (str:string): string { // elide TS types for js-compatibility
return str.split('').map(ch => '0x' + ch.charCodeAt(0).toString(16)).join(', ')
}
%}
%lex
%no-break-if (.*[^a-z] | '') 'return' ([^a-z].* | '') // elide trailing 'break;'
%%
\s+ if (yy.trace) yy.trace(`skipping whitespace ${hexlify(yytext)}`)
[0-9]+("."[0-9]+)?\b return 'NUMBER'
"-" return '-'
"+" return '+'
"(" return '('
")" return ')'
<<EOF>> return 'EOF'
. return 'INVALID'
/lex
%left '+' '-'
%left UMINUS
%start expr
%%
expr: e EOF { if (yy.trace)
yy.trace('returning', $1);
return $1; } ; // return e
e : e '+' e {$$ = $1+$3;}
| e '-' e {$$ = $1-$3;}
| '-' e %prec UMINUS {$$ = -$2;}
| '(' e ')' {$$ = $2;}
| NUMBER {$$ = Number(yytext);} ;
See packages/parser-generator/examples/ for examples and scripts for invocation.
Convert the .jison file to a TS file:
ts-jison -t typescript -n TsCalc -n TsCalc -o ts-calculator.ts ts-calculator.jison
Convert the .jison file to a JS file:
ts-jison -n TsCalc -n TsCalc -o js-calculator.js js-calculator.jison
const ParserAndLexer = require('./ts-calculator');
const txt = ``;
const res = new ParserAndLexer.TsCalcParser().parse(txt);
console.log(txt.trim(), '=', res);
or for JS:
const ParserAndLexer = require('./js-calculator');
See parser-generator docs for more details.
git clone ...
cd <cloned repo>
npm ci
for d in packages/{common,lexer,parser}/; do (cd $d && tsc -b tsconfig.package.json); done
lerna bootstrap
npm t
During development, you have to repeat the lerna bootstrap
command to get to a steady state because bootstrap tests that the build worked and doesn't seem to reliably build in the order of package dependencies (PRs welcome!).
See CONTRIBUTING.md for contribution guidelines, how to run the tests, etc.
View them on the wiki, or add your own.
Special thanks to Jarred Ligatti, Manuel E. Bermúdez
Please see the license in this directory.