Package: rbnf-rts
rbnf-rtsRuntime support for generated parsers of RBNF.hsP.S:rbnf-rtsis the new fastest Python parser generator by 2020, according to a benchmark given bybenchmark-json.FeaturesSyntax-drivenLeft recursion with LL parsing(yes, left recur in LL, it's right)Grammar inline optimizationsSmarter lookahead via ID3 algorithmStatically generated(no need to create the parser again and again when starting your application)Good error reports(including the position and nested rule names of parsing error)RBNF.hs is language independent[WIP]: context sensitive parsing as an extension to CFGMore ExamplesCheck thetestdirectory:testmultiply : parser/lexer implementation for multiplicationsarith : parser/lexer implementation for arithmeticsrelax : parser/lexer implementation for a full-featured programming languagellvmir: parser/lexer implementation for LLVM IR, nearly full-featuredrbnfjson: a json parser implemented by RBNF.hs and rbnf-rtsIn each sub-directory of test, you can run tests via directly invoking the test.sh., likecd test/llvmir && bash test.shNative DependenciesThe Haskell Stack ToolchainThe executablerbnf-pgenin PATH.If~/.local/binis already in PATH:git clone https://github.com/thautwarm/RBNF.hs
cd RBNF.hs
stack install .Example: Multiplicationswrite amultiply.exrbnffile# 'mul' is a python global which should be marked as 'required' in .rlex
Mul    : lhs=Mul "*" rhs=Atom { mul(lhs, rhs) }
       | a=Atom  {a}
       ;

# 'unwrap' should be marked as 'required', just as 'mul'
Atom   :  "(" !a=Mul ")"  {a} ;
       |  <number>        { unwrap($0) };
START ::= <BOF> Mul <EOF> { $1 };or write amultiply.rbnffile:# 'mul' is a python global which should be marked as 'required' in .rlex
Mul    : !lhs=Mul "*" !rhs=Atom            -> mul(lhs, rhs);
Mul    : !a=Atom                           -> a;
Atom   : "(" !a=Mul ")"                    -> a;

# 'unwrap' should be marked as 'required', just as 'mul'
Atom   : !a=<number>                       -> unwrap(a);
START ::= <BOF> !a=Mul <EOF>               -> a;write amultiply.rlexfile:%require mul
%require unwrap
%ignore space
number [+-]?\d+
space \s+codegensh>rbnf-pygenmultiply.rbnfmultiply.rlexmultiply.py--k1--tracebackrun statically-generated parsers and lexers and enjoy its efficiencyfromrbnf_rts.rtsimportTokens,Statefrommultiplyimportrun_lexer,mk_parserimportoperatordefunwrap(x:Token):returnint(x.value)scope=dict(mul=operator.mul,unwrap=unwrap)parse=mk_parser(**scope)tokens=list(run_lexer("<current file>","-1 * 2 * (3 * 4)"))got=parse(State(),Tokens(tokens))print(got)Got(True, -24), whereTrueindicates the parsing succeeded.IfFalse, a list of errors will be given in the second element of
the return tuple.Menhir-like syntax sugars includinglistandseparated_list.A json parser more than 20% efficient than that of lark-parser(lol), written as a.exrbnffile.START: <BOF> value <EOF> { $1 };

value: <ESCAPED_STRING> { DQString(*$0) }
     | <SIGNED_INT>     { int(*$0) }
     | <SIGNED_FLOAT>   { float(*$0) }
     | "true" { True }
     | "null" { None }
     | "false" { False }
     # array
     | '[' ']' {[]}
     | '[' separated_list(',', value) ']' { $1 }
     # object
     | '{' '}' { dict() }
     | '{' separated_list(',', pair) '}' { dict($1) }
     ;
pair   : <ESCAPED_STRING> ":" value { (DQString(*$0), $2) };Checkrbnfjsonfor more information.