Example #1
0
def test_simple_ml():
    _test_simple_ml()
    ze_exp.lang.as_fixed()
    _test_simple_ml()

    parse = build_parser(ze_exp.lang, opt=True)
    print(parse("let x = 1 in x"))
Example #2
0
engine ::= 'engine'
           '{'
              kvs=(kv (',' kv)*)
           '}' -> Engine(dict(kvs))
id     ::= name=Name -> name.value
python ::= mark='python' codes=(_{is_indented})+ -> Python(recover_codes([mark, *codes])[len('python'):])
field  ::= id=id ':' type=expr ops=option* ['=' value=expr] -> Field(id, type, ops, value)
fields ::= fields<<field (',' fields<<field)* [','] -> fields
repr   ::= '{' names=(id (',' id)*) '}' -> names[::2]
table  ::= id=id
           '{' 
                [fields=fields]
                ['repr' repr=repr] 
           '}' -> Table(id, fields or [], repr)
option ::= ch=('~' | '!' | '?') -> ch.value
relation ::= left=id w1=['^'] 'with' w2=['^'] right=id
             '{' 
                field_lst=(field (',' field)*)
             '}' -> Relation(left, right, (bool(w1), bool(w2)), field_lst[::2])
expr   ::=  | [is_enum='enum'] tks=(~('=' | '{' | '}' | '!' | '?' | '~' | ',' | 'repr' | 'with'))+ 
           -> (EnumValue if is_enum else Value)(recover_codes(tks))  
lexer_helper := R'.'
stmts  ::= stmts=(engine | relation | table | python)+ -> list(stmts)

"""
dbg = Language('dbg')
dbg.namespace.update(dbg_ast.__dict__)
build_language(source_code, dbg, 'dbg-lang.rbnf')
parse = build_parser(dbg)

Example #3
0
import re
from rbnf.easy import Language, build_language, build_parser
from ast import fix_missing_locations
from astpretty import pprint
from rbnfrbnf import constructs
with open('rbnf-bootstrap.rbnf') as f:
    code = f.read()

rbnf2 = Language('rbnf')
rbnf2.namespace.update(constructs.__dict__)
build_language(code, rbnf2, "rbnf-bootstrap.rbnf")
test_line_start = re.compile('\S')
parse = build_parser(rbnf2)


def add_semi_comma(text: str):
    def _add_semi_comma(text_formal: str):
        for each in text_formal.split('\n'):
            if test_line_start.match(each):
                yield ';'
            yield each

    return '\n'.join(_add_semi_comma(text))


result = parse(
    add_semi_comma("""
X := 'a'
A ::= ('b' | 'c' ('c' | 'a'))
Z ::= 'b'
recur F ::= 
Example #4
0
keyword cast := 'commit' 'Author:'
sig := R'[0-9a-f]+'

space := R'\n|\s+'

head ::= 'commit' as mark 
                space sig as sig (~'\n')* '\n'
         (~'Author:')*
         'Author:' 
                 (~'<')+ as author '<' (~'>')+ as email '>'
         with mark.colno <= 1
         rewrite sig.value, ''.join(e.value for e in author).strip(), ''.join(e.value for e in email).strip()

section ::= head as sig (~head)+
            rewrite sig
            
lexer_helper := R'.'
partial_text ::= (~section)* section as it
                 rewrite it
                 
text ::= (section to [it] | ~section)+
         rewrite it
"""

lang = Language("git-log")

build_language(grammar, lang, '<python-internal>')

parse = build_parser(lang, use_parser='text')
partial_parse = build_parser(lang, use_parser='partial_text')
Example #5
0
from rbnfrbnf.core import constructs
import re
import os

cfg = Language('cfg-rbnf')
test_line_start = re.compile('\S')


def add_semi_comma(text: str):
    def _add_semi_comma(text_formal: str):
        for each in text_formal.split('\n'):
            if test_line_start.match(each):
                yield ';'
            yield each
        yield ';'

    return '\n'.join(_add_semi_comma(text))


directory = os.path.split(__file__)[0]
with open(f'{directory}/context_free.rbnf') as f:
    source = f.read()

cfg.namespace = {**constructs.__dict__}
build_language(source, cfg, 'context_free.rbnf')
_parse = build_parser(cfg)


def parse(grammar):
    return _parse(add_semi_comma(grammar))
Example #6
0
def run(filename: 'python file generated by `rbnf` command, or rbnf sour file',
        opt: 'optimize switch' = False):
    """
    You can apply immediate tests on your parser.
    P.S: use `--opt` option takes longer starting time.
    """
    from rbnf.easy import build_parser
    import importlib.util
    import traceback
    full_path = Path(filename)
    base, ext = os.path.splitext(str(full_path))
    full_path_str = str(full_path)

    if not ext:
        if full_path.into('.py').exists():
            full_path_str = base + '.py'
        elif Path(base).into('.rbnf'):
            full_path_str = base + '.rbnf'

    if full_path_str[-3:].lower() != '.py':
        with Path(full_path_str).open('r') as fr:
            ze_exp = ze.compile(fr.read(), filename=full_path_str)
            lang = ze_exp.lang

    else:
        spec = importlib.util.spec_from_file_location("runbnf", full_path_str)

        mod = importlib.util.module_from_spec(spec)
        spec.loader.exec_module(mod)
        try:
            lang = next(each for each in mod.__dict__.values()
                        if isinstance(each, Language))
        except StopIteration:
            raise NameError("Found no language in {}".format(full_path_str))

    parse = build_parser(lang, opt=bool(opt))
    namespace = {}

    print(Purple('type `:i` to switch between python mode and parsing mode.'))
    print(Purple('The last result of parsing is stored as symbol `res`.'))
    while True:

        inp = input('runbnf> ')
        if not inp.strip():
            continue
        elif inp.strip() == 'exit':
            break

        if inp.strip() == ':i':
            while True:
                inp = input('python> ')

                if inp.strip() == ':i':
                    break
                try:
                    try:
                        res = eval(inp, namespace)
                        if res is not None:
                            print(res)

                        namespace['_'] = res
                    except SyntaxError:
                        exec(inp, namespace)
                except Exception:
                    traceback.print_exc()
        else:
            res = namespace['res'] = parse(inp)
            print(
                LightBlue(
                    'parsed result = res: ResultDescription{result, tokens, state}'
                ))
            print(res.result)