1919
2020import sys
2121import string
22+ import operator
23+ import itertools
24+
2225from pyparsing import *
2326
27+ try : from functools import reduce
28+ except : pass
29+
2430class Expression :
2531 def __init__ (self , contents ):
2632 self .contents = contents [0 ]
@@ -56,12 +62,12 @@ def __repr__(self):
5662class Terminal :
5763 def __init__ (self , contents ):
5864 self .contents = contents [0 ]
59- def __repr__ (self ):
6065 s = self .contents
61- is_keyword = len (s ) >= 4 and s [0 ::len (s )- 1 ] == '""' and \
66+ self . is_keyword = len (s ) >= 4 and s [0 ::len (s )- 1 ] == '""' and \
6267 all (c in alphanums + "_" for c in s [1 :- 1 ])
63- ty = "CaselessKeyword" if is_keyword else "CaselessLiteral"
64- return "%s(%s)" % (ty , s )
68+ def __repr__ (self ):
69+ ty = "CaselessKeyword" if self .is_keyword else "CaselessLiteral"
70+ return "%s(%s)" % (ty , self .contents )
6571
6672
6773LPAREN = Suppress ("(" )
@@ -94,16 +100,16 @@ def __repr__(self):
94100
95101express = grammar .parseFile (sys .argv [1 ])
96102
97- def find_keywords (expr , li = None ):
103+ def find_bytype (expr , ty , li = None ):
98104 if li is None : li = []
99105 if isinstance (expr , Term ):
100106 expr = expr .contents
101- if isinstance (expr , Keyword ):
102- li .append (repr ( expr ) )
103- return li
107+ if isinstance (expr , ty ):
108+ li .append (expr )
109+ return set ( li )
104110 elif isinstance (expr , Expression ):
105111 for term in expr :
106- find_keywords (term , li )
112+ find_bytype (term , ty , li )
107113 return set (li )
108114
109115actions = {
@@ -122,25 +128,31 @@ def find_keywords(expr, li = None):
122128 'inverse_attr' : "lambda t: InverseAttribute(t)" ,
123129 'bound_spec' : "lambda t: BoundSpecification(t)" ,
124130 'explicit_attr' : "lambda t: ExplicitAttribute(t)" ,
131+ 'width_spec' : "lambda t: WidthSpec(t)" ,
132+ 'string_type' : "lambda t: StringType(t)" ,
125133}
126134
127135to_emit = set (id for id , expr in express )
128136emitted = set ()
129137to_combine = set (["simple_id" ])
130138to_ignore = set (["where_clause" , "supertype_constraint" , "unique_clause" ])
131139statements = []
140+
141+ terminals = reduce (lambda x ,y : x | y , (find_bytype (e , Terminal ) for id , e in express ))
142+ keywords = list (filter (operator .attrgetter ('is_keyword' ), terminals ))
143+ negated_keywords = map (lambda s : "~%s" % s , keywords )
132144
133145while True :
134146 emitted_in_loop = set ()
135147 for id , expr in express :
136- kws = find_keywords ( expr )
148+ kws = map ( repr , find_bytype ( expr , Keyword ) )
137149 found = [k in emitted for k in kws ]
138150 if id in to_emit and all (found ):
139151 emitted_in_loop .add (id )
140152 emitted .add (id )
141153 stmt = "(%s)" % expr
142154 if id in to_combine :
143- stmt = "originalTextFor(Combine%s)" % stmt
155+ stmt = " + " . join ( itertools . chain ( negated_keywords , ( " originalTextFor(Combine%s)" % stmt ,)))
144156 if id in actions :
145157 stmt = "%s.setParseAction(%s)" % (stmt , actions [id ])
146158 statements .append ("%s = %s" % (id , stmt ))
0 commit comments