paka.js
Paka.js is a higher-order function based parser combinator. It's designed for creating language parsers in JavaScript. Unlike external parser generators such as ANTLR, there's no static code generation involved. When writing language parsers in JavaScript, you can define the language grammar and semantics actions with the embedded DSL of paka.js. It is much light-weighted than external parser generators.
Examples
1. Caculator
The following code implements a working caculator in less than 100 lines of code. The hightlight is that the language grammar is written in the embedded DSL, it's clean and easy to maintain.
var paka = ; { var INT = pakaINT; var EOF = pakaEOF; var CONCAT = pakaCONCAT; var OR = pakaOR; var LIST = pakaLIST; var $ = paka$; var grammar = 'Arithmetic' : 'Expr' : 'Term' : 'TermOp' : 'Factor' : 'FactorOp' : 'P-Expr' : 'Num' : ; var actions = { rextra = ; } { rextra = rchildren0extra; } { rextra = rchildren0extra; for var i = 1; i < rchildrenlength; i += 2 var factor_op = rchildreni; var factor = rchildreni+1; if '*' == factor_optext rextra *= factorextra; else if '/' == factor_optext rextra /= factorextra; } { rextra = rchildren0extra; for var i = 1; i < rchildrenlength; i += 2 var factor_op = rchildreni; var factor = rchildreni+1; if '+' == factor_optext rextra += factorextra; else if '-' == factor_optext rextra -= factorextra; } { rextra = rchildren1extra; } { rextra = rchildren0extra; } var parser = paka; var ast = parser; if pakaSOK == aststatus console; else console; }
2. JSON Parser
The following code implements a JSON parser which creates a JSON object from its string representation. Reference: http://www.json.org/fatfree.html
{ var NUM = pakaNUM; var EOF = pakaEOF; var CONCAT = pakaCONCAT; var OR = pakaOR; var REPEAT = pakaREPEAT; var OPT = pakaOPT; var DQ_STR = pakaDQ_STR; var ENCLOSED_LIST = pakaENCLOSED_LIST; var $ = paka$; var grammar = 'JSON' : 'Value' : 'Object' : 'KeyValuePair' : 'Key' : 'Num' : 'Null' : 'null' 'Bool' : 'String' : 'Array' : ; var actions = { rextra = ; } { rextra = null } { rextra = 'true' == rtext; } { rextra = ; } { } { rextra = rchildren0extra; } { rextra = key : rchildren0extra value : rchildren2extra ; } { rextra = {}; for var i = 0; null != rchildren && i < rchildrenlength; ++i rextrarchildreniextrakey = rchildreniextravalue; } { rextra = ; for var i = 0; null != rchildren && i < rchildrenlength; ++i rextra; } { rextra = rchildren0extra; } var parser = paka; var ast = parser; return ast;}