source: proto/RE2PBS/re2pbs.g @ 1154

Last change on this file since 1154 was 1154, checked in by ksherdy, 9 years ago

Minor template fixes.

File size: 6.9 KB
Line 
1/*
2
3  AnTLR Grammar (Python)
4
5  Regular Expressions to Parallel Bit Stream equation generator.
6
7  Copyright (c) 2011, Ken Herdy
8
9  Version 0.7 - April 15, 2011
10 
11      Restricted meta character handling. All meta characters (character class meta characters, global regular expression meta characters)
12      must be escaped at all scopes/context.
13      Use of hexadecimal escapes to specify newline characters.
14      Support alternation, concatenation, repetition operators ('?','+','*')
15
16  Version 0.8
17
18      TODO -    Add precedence via grouping operator.
19
20                Two pass implementation to support regular expression escape characters at both the
21                the global and character class scopes.
22               
23                i.e.    Pass One - Character class scope pass.
24                        Pass Two - Global scope pass.
25*/
26grammar re2pbs;
27
28options {       
29        language = Python;
30}
31
32@header {
33        # --------------------------------------------------------------------------------
34        # Imports       
35        # --------------------------------------------------------------------------------
36        from re2pbs import *
37        from codepoint_symbol_table import CodePointSymbolTable, CodePointSymbol
38        from charset_compiler import chardeflist2py
39        from charset_def import CharSetDef
40
41        # --------------------------------------------------------------------------------
42        # Methods
43        # --------------------------------------------------------------------------------
44        def codepoints2chardefsets(codepointss):
45                """ Translates 'lists of lists' of code points Character Class Compiler CharSetDef argument list syntax """       
46                lst = []       
47                       
48                for codepoints in codepointss: 
49                  lgth = len(codepoints)
50
51                  if lgth < 1:
52                    raise BadCodePointException
53                  elif lgth == 1:
54                    lst.append(chr(codepoints[0]))
55                  elif lgth == 2:
56                    lst.append(chr(codepoints[0]) + '-' + chr(codepoints[1]))
57                  else:
58                    raise BadCodePointException
59               
60                return lst
61
62
63        def generate_chardefsets(symbol_table_items, prefix=''):
64                defs = []
65                for key, symbol in symbol_table_items:
66                        defs.append(CharSetDef(prefix + key, codepoints2chardefsets(symbol.codepoints), symbol.invert))
67                return defs
68
69        # TODO - relocate
70        def generate_pbs_code_concatenations(generator_factory, concatenations, prefix='', level=1, debug=True):
71                pbs_code = ''
72                pbs_debug = ''
73                lgth = len(concatenations)
74
75                for i in range(0,lgth):
76                        pre_validator_generator = generator_factory.build_pre_validator(level, 'cursor','error') 
77                        (code, debug) = generate_pbs_code_atoms(pre_validator_generator, concatenations[i].atom_list, prefix)
78                        pbs_code += code
79                        pbs_debug += debug
80
81                #TODO - glue concatenation list pbs code, glue debug code
82
83                return (pbs_code, pbs_debug)
84
85        # TODO - relocate
86        def generate_pbs_code_atoms(generator, atoms, prefix='', debug=True):
87                pbs_code = ''
88                pbs_debug = ''
89                lgth = len(atoms)
90
91                if lgth > 0:
92                        pbs_code = generator.make_init_stmts(prefix + atoms[0].strm_name)
93               
94                        for i in range(0,lgth):
95                                pbs_code += generator.make_match_stmts(prefix + atoms[i].strm_name, atoms[i].quantifier, None)
96
97                        pbs_code += generator.make_finalization_stmts()
98                        pbs_debug += generator.make_debug_stmts()
99
100                return (pbs_code, pbs_debug)
101}
102
103@members {
104        symbol_table = CodePointSymbolTable()
105}
106
107@lexer::header {
108}
109
110@lexer::members {
111}
112
113prog    :       r = re EOF
114{
115        lex_strms = ''
116        cc_code = ''
117        pbs_code = ''
118        pbs_debug = ''
119
120        factory = GeneratorFactory()
121
122        lex_strms = Generator.make_lexical_items(self.symbol_table.symbols.keys())
123        cc_code = chardeflist2py(generate_chardefsets(self.symbol_table.symbols.items(), 'lex.'))
124        #print cc_code
125
126        (pbs_code, pbs_debug) = generate_pbs_code_concatenations(factory, r.union.concatenation_list, 'lex.')   
127
128        print lex_strms
129        print cc_code
130        print pbs_code
131        print pbs_debug
132       
133        prototype = Program()
134        prototype.generate(lex_strms, cc_code, pbs_code, pbs_debug)
135
136}
137        ;
138               
139re      returns [object]
140@init {
141        object = RE()
142}
143@after {
144        # print object.debug()
145}
146        :       (union
147                        {       
148                                object.union = $union.object
149                        }
150                )?
151        ;       
152       
153union   returns [object]
154@init {
155        object = Union()       
156}
157@after {
158        #print object.debug()
159}
160        :       c0 = concatenation             
161                {
162                        # initialize an object
163                        object.concatenation_list.append(c0)
164
165                }
166                (
167                Or ck = concatenation   
168                {
169                        # initialize an object
170                        object.concatenation_list.append(ck)
171                } 
172                )*
173        ;
174       
175concatenation returns [object]
176@init {
177        object = Concatenation()
178}
179@after {
180        #print object.debug()
181}
182        : (atom {object.atom_list.append($atom.object)})+
183        ;       
184
185atom returns [object]
186@init {
187        symbol = CodePointSymbol()     
188        object = Atom()     
189}
190@after {
191       
192        self.symbol_table.insert(symbol.key(), symbol)                 
193        #print object.debug()
194}
195        :
196        (
197        single  {
198                        symbol.add_codepoint($single.object.codepoint)
199                        object.strm_name = symbol.key()
200                }
201        |
202        characterClass 
203                {       
204                        for obj in $characterClass.object.single_or_range:
205                                if isinstance(obj,Single):
206                                        symbol.add_codepoint(obj.codepoint, $characterClass.object.invert)
207                                elif isinstance(obj,Range):
208                                        symbol.add_codepoint_range(obj.codepoint_lower, obj.codepoint_upper, $characterClass.object.invert)
209                        object.strm_name = symbol.key()
210                }
211        )
212        (Quantifier {object.quantifier = $Quantifier.text})?
213        ;
214       
215characterClass  returns [object]
216@init {
217        object = CharacterClass()
218}
219@after {
220        #object.debug()
221}
222        :
223        SquareBracketStart                     
224        (Caret  {object.invert = True})?
225        (
226        range           {object.single_or_range.append($range.object)}
227        |
228        single          {object.single_or_range.append($single.object)}
229        )+
230        SquareBracketEnd                       
231        ;
232       
233range   returns [object]
234@init{
235        object = Range()
236}
237@after {
238        #object.debug()
239}
240        :       lb = single {object.codepoint_lower = $lb.object.codepoint}     
241               
242                Hyphen
243               
244                ub = single {object.codepoint_upper = $ub.object.codepoint}     
245                                                                       
246        ;       
247       
248single  returns [object]
249@init{
250        object = Single()
251}
252@after {
253        #object.debug()
254}
255        : i = UnicodeCharacter                                  {object.codepoint = int($i.text[2:],16)}
256                                                                       
257        | j = SmallHexNumber                                    {object.codepoint = int($j.text[2:],16)}
258                                                                       
259        | k = EscapeSuperMetaCharacter                          {object.codepoint = ord($k.text[1:])}
260
261        | l = NotSuperMetaCharacter                             {object.codepoint = ord($l.text[(len($l.text)-1):])}
262                                                                                                                                               
263        ;       
264
265// Lexical
266NewLine            :  ('\r''\n' | '\n' | '\r' )     {$channel=HIDDEN;}  ; // LFCR - Windows | LF - Unix | CR - Mac --> Specifiy using Unicode or Small Hex Escape
267
268// Supermetacharacters
269Escape             :  '\\'     ;
270Or                 :  '|'      ;
271SquareBracketStart :  '['      ;       
272Hyphen             :  '-'      ;       
273Caret              :  '^'      ;       
274SquareBracketEnd   :  ']'      ;       
275
276
277UnicodeCharacter
278        : Escape 'u' HexDigit HexDigit HexDigit HexDigit
279        ;       
280
281SmallHexNumber
282        : Escape 'x' HexDigit HexDigit
283        ;
284
285fragment
286HexDigit
287        : ('0'..'9' | 'a'..'f' | 'A'..'F')
288        ;
289
290EscapeSuperMetaCharacter
291        : Escape SuperMetaCharacters
292        ;
293       
294NotSuperMetaCharacter
295        : ~(SuperMetaCharacters)
296        ;       
297       
298fragment
299SuperMetaCharacters
300        : (QuestionMark | Star | Cross | Or | SquareBracketStart | SquareBracketEnd | Hyphen | Escape | Caret)
301        ;
302       
303Quantifier
304        :  QuestionMark
305        |  Star
306        |  Cross
307        ;       
308
309fragment
310QuestionMark       :  '?'      ;       
311
312fragment
313Star               :  '*'      ;       
314
315fragment
316Cross              :  '+'      ;       
317
Note: See TracBrowser for help on using the repository browser.