-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy patheg_metapeg.py
77 lines (63 loc) · 3.32 KB
/
eg_metapeg.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
"""
Useless example grammar for testing.
"""
from parson import *
def meta_mk_feed(name):
def fn(*args): return '%s(%s)' % (name, ' '.join(map(repr, args)))
return label(feed(fn), ':'+name)
def meta_mk_rule_ref(name): return '<'+name+'>' # XXX
def mk_empty(): return empty
def fnordify(peg): return peg #+ '<FNORD>'
meta_grammar = r""" rule+ :end | anon :end.
anon : :None :'' [:'' :literal fnordly pe :chain] :hug ('.' rule*)?.
rule : name {'~'?} ('=' pe
|':'~whitespace [pe :seclude])
'.' :hug.
pe : term ('|' pe :either)?
| :mk_empty.
term : factor (term :chain)?.
factor : '!' factor :invert
| primary ('**' primary :star
|'++' primary :plus
|'*' :star
|'+' :plus
|'?' :maybe)?.
primary : '(' pe ')'
| '[' pe ']' :seclude
| '{' pe '}' :capture
| qstring :literal fnordly
| dqstring :literal fnordly
| regex :match fnordly
| ':'~( name :meta_mk_feed
| qstring :push)
| name :meta_mk_rule_ref.
fnordly = ('~' | :fnordify).
name : /([A-Za-z_]\w*)/.
FNORD ~: whitespace?.
whitespace ~: /(?:\s|#.*)+/.
qstring ~: /'/ quoted_char* /'/ FNORD :join.
dqstring ~: '"' dquoted_char* '"' FNORD :join.
regex ~: '/' regex_char* '/' FNORD :join.
quoted_char ~: /\\(.)/ | /([^'])/.
dquoted_char~: /\\(.)/ | /([^"])/.
regex_char ~: /(\\.)/ | /([^\/])/.
"""
metapeg = Grammar(meta_grammar)(**globals())
## for k, af, v in metapeg(meta_grammar): print k, af, v
#. None (literal('') ((('<rule>')+ :end)|('<anon>' :end)))
#. anon [(:None (push('') ([(push('') (:literal ('<fnordly>' ('<pe>' :chain))))] (:hug ((literal('.') ('<rule>')*))?))))]
#. rule [('<name>' (capture((literal('~'))?) (((literal('=') '<pe>')|(literal(':') ('<whitespace>' [('<pe>' :seclude)]))) (literal('.') :hug))))]
#. pe [(('<term>' ((literal('|') ('<pe>' :either)))?)|:mk_empty)]
#. term [('<factor>' (('<term>' :chain))?)]
#. factor [((literal('!') ('<factor>' :invert))|('<primary>' (((literal('**') ('<primary>' :star))|((literal('++') ('<primary>' :plus))|((literal('*') :star)|((literal('+') :plus)|(literal('?') :maybe))))))?))]
#. primary [((literal('(') ('<pe>' literal(')')))|((literal('[') ('<pe>' (literal(']') :seclude)))|((literal('{') ('<pe>' (literal('}') :capture)))|(('<qstring>' (:literal '<fnordly>'))|(('<dqstring>' (:literal '<fnordly>'))|(('<regex>' (:match '<fnordly>'))|((literal(':') (('<name>' :meta_mk_feed)|('<qstring>' :push)))|('<name>' :meta_mk_rule_ref))))))))]
#. fnordly (literal('~')|:fnordify)
#. name [/([A-Za-z_]\w*)/]
#. FNORD ~ [('<whitespace>')?]
#. whitespace ~ [/(?:\s|#.*)+/]
#. qstring ~ [(/'/ (('<quoted_char>')* (/'/ ('<FNORD>' :join))))]
#. dqstring ~ [(literal('"') (('<dquoted_char>')* (literal('"') ('<FNORD>' :join))))]
#. regex ~ [(literal('/') (('<regex_char>')* (literal('/') ('<FNORD>' :join))))]
#. quoted_char ~ [(/\\(.)/|/([^'])/)]
#. dquoted_char ~ [(/\\(.)/|/([^"])/)]
#. regex_char ~ [(/(\\.)/|/([^\/])/)]