def peglet_to_parson(text): nonterminals = set() def equ(name, space): nonterminals.add(name) return name, space, ': ' g = grammar(equ=alter(equ), mk_regex=mk_regex) tokens = g.grammar(text) return ''.join(':'+token if re.match(name+'$', token) and token not in nonterminals else token for token in tokens)
def peglet_to_parson(text): nonterminals = set() def equ(name, space): nonterminals.add(name) return name, space, ': ' g = grammar(equ=alter(equ), mk_regex=mk_regex) tokens = g.grammar(text) return ''.join( ':' + token if re.match(name + '$', token) and token not in nonterminals else token for token in tokens)
def nullify(fn): def nullified(*args): fn(*args) return () return alter(nullified)
""" Tiny example of 'compiling'. """ from parson import Grammar, alter g = Grammar(r""" stmt* :end. stmt : ident '=' exp0 ';' :assign. exp0 : exp1 ('+' exp1 :'add')*. exp1 : exp2 ('*' exp2 :'mul')*. exp2 : '(' exp0 ')' | /(\d+)/ | ident :'fetch'. ident : /([A-Za-z]+)/. FNORD ~: /\s*/. """)(assign=alter(lambda name, *rpn: rpn + (name, 'store'))) ## print ' '.join(g('v = 42 * (5+3) + 2*2; v = v + 1;')) #. 42 5 3 add mul 2 2 mul add v store v fetch 1 add v store
def nullify(fn): return alter(lambda *args: (fn(*args), ())[1]) # XXX kinda ugh
opid : /([~!@%&*\-+=|\\<>,?\\\/]+)/. number : /(-?\d+)/ :int. string : /'((?:''|[^'])*)'/. FNORD ~: whitespace*. whitespace ~: /\s+|-- .*/. """ # XXX string literals with '' need unescaping def mk_block_method(params, body): cue = ('of',) + ('and',)*(len(params)-1) if params else ('run',) return Method(cue, params, body) def mk_body(*exprs): return Nest(reduce(Then, exprs)) unzip = alter(lambda *parts: (parts[0::2], parts[1::2])) parse = Grammar(parser_grammar)(**globals()).program # Smoke test ## parse('adjoining of (k + 5) to empty')[0] #. {adjoining of (k + 5) to empty} ## parse(': { 1 }')[0] #. {:: {run: {1}}} text1 = """ empty :: { is-empty: { yes } ; has k: { no }