source: trunk/yao/share/antlr-2.7.7/antlr/actions/csharp/action.g @ 1

Last change on this file since 1 was 1, checked in by lnalod, 15 years ago

Initial import of YAO sources

File size: 9.9 KB
Line 
1header {
2        package antlr.actions.csharp;
3}
4
5{
6        import java.io.StringReader;
7        import antlr.collections.impl.Vector;
8        import antlr.*;
9}
10
11/* ANTLR Translator Generator
12 * Project led by Terence Parr at http://www.cs.usfca.edu
13 * Software rights: http://www.antlr.org/license.html
14 *
15 * Port to C# by Kunle Odutola : kunle UNDERSCORE odutola AT hotmail DOT com
16 *
17 * $Id:$
18 */
19
20// HISTORY:
21//
22// 01-Aug-2002 kunle    Now handles C# preprocessor directives
23//                                              [ Based on Ric's C/C++ preprocessor code ]
24// 07-Dec-2002 kunle    Now supports the new #[ID,text,nodeType] syntax.
25//
26
27
28/** Perform the following translations:
29
30    AST related translations
31
32        ##                              -> currentRule_AST
33        #(x,y,z)                -> codeGenerator.getASTCreateString(vector-of(x,y,z))
34        #[x]                    -> codeGenerator.getASTCreateString(x)
35        #x                              -> codeGenerator.mapTreeId(x)
36
37        Inside context of #(...), you can ref (x,y,z), [x], and x as shortcuts.
38
39    Text related translations
40
41        $append(x)        -> text.append(x)
42        $setText(x)       -> text.setLength(_begin); text.append(x)
43        $getText          -> new String(text.getBuffer(),_begin,text.length()-_begin)
44        $setToken(x)  -> _token = x
45        $setType(x)       -> _ttype = x
46    $FOLLOW(r)    -> FOLLOW set name for rule r (optional arg)
47    $FIRST(r)     -> FIRST set name for rule r (optional arg)
48 */
49class ActionLexer extends Lexer;
50options {
51        k=3;
52        charVocabulary='\3'..'\377';
53        testLiterals=false;
54        interactive=true;
55}
56
57{
58        protected RuleBlock currentRule;
59        protected CodeGenerator generator;
60        protected int lineOffset = 0;
61        private Tool antlrTool; // The ANTLR tool
62        ActionTransInfo transInfo;
63
64        public ActionLexer( String s, RuleBlock currentRule,
65                                                CodeGenerator generator,
66                                                ActionTransInfo transInfo )
67        {
68                this(new StringReader(s));
69                this.currentRule = currentRule;
70                this.generator = generator;
71                this.transInfo = transInfo;
72        }
73
74        public void setLineOffset(int lineOffset)
75        {
76                setLine(lineOffset);
77        }
78
79        public void setTool(Tool tool)
80        {
81                this.antlrTool = tool;
82        }
83
84        public void reportError(RecognitionException e)
85        {
86                antlrTool.error("Syntax error in action: "+e,getFilename(),getLine(),getColumn());
87        }
88
89        public void reportError(String s)
90        {
91                antlrTool.error(s,getFilename(),getLine(),getColumn());
92        }
93
94        public void reportWarning(String s)
95        {
96                if ( getFilename()==null )
97                        antlrTool.warning(s);
98                else
99                        antlrTool.warning(s,getFilename(),getLine(),getColumn());
100        }
101}
102
103// rules are protected because we don't care about nextToken().
104
105public
106ACTION
107        :       (       STUFF
108                |       AST_ITEM
109                |       TEXT_ITEM
110                )+
111        ;
112
113/** stuff in between #(...) and #id items
114 * Allow the escaping of the # for C# preprocessor stuff.
115 */
116protected
117STUFF
118        :       COMMENT
119        |       STRING
120        |       CHAR
121        |       "\r\n"          { newline(); }
122        |       '\\' '#'        { $setText("#"); }
123        |       '\r'            { newline(); }
124        |       '\n'            { newline(); }
125        |       '/' ~('/'|'*')  // non-comment start '/'
126//      |       ( ~('/'|'\n'|'\r'|'$'|'#'|'"'|'\'') )+
127        |       ~('/'|'\n'|'\r'|'$'|'#'|'"'|'\'')
128        ;
129
130protected
131AST_ITEM
132        :       '#'! t:TREE                                                                                                     // #( )
133        |       '#'! (WS)? id:ID                                                                                        // #a_name (=)?
134                {
135                        String idt = id.getText();
136                        String mapped = generator.mapTreeId(id.getText(), transInfo);
137
138                        // verify that it's not a preprocessor macro...
139                        if ( (mapped != null) && !idt.equals(mapped) )
140                        {
141                                $setText(mapped);
142                        }
143                        else
144                        {
145                                if (idt.equals("define")        ||
146                                        idt.equals("undef")             ||
147                                        idt.equals("if")                ||
148                                        idt.equals("elif")              ||
149                                        idt.equals("else")              ||
150                                        idt.equals("endif")             ||
151                                        idt.equals("line")              ||
152                                        idt.equals("error")             ||
153                                        idt.equals("warning")   ||
154                                        idt.equals("region")    ||
155                                        idt.equals("endregion"))
156                                {
157                                        $setText("#"+idt);
158                                }
159                        }
160                }
161                (WS)?
162                ( options {greedy=true;} : VAR_ASSIGN )?
163        |       '#'! ctor:AST_CONSTRUCTOR                                                               // #[ ]
164        |       "##"
165                {
166                        if( currentRule != null )
167                        {
168                                String r = currentRule.getRuleName()+"_AST";
169                                $setText(r);
170
171                                if ( transInfo!=null )  {
172                                        transInfo.refRuleRoot=r;        // we ref root of tree
173                                }
174                        }
175                        else
176                        {
177                                reportWarning("\"##\" not valid in this context");
178                                $setText("##");
179                        }
180                }
181                (WS)?
182                ( options {greedy=true;} : VAR_ASSIGN )?
183        ;
184
185protected
186TEXT_ITEM
187        :       "$append" (WS)? '(' a1:TEXT_ARG ')'
188                {
189                        String t = "text.Append("+a1.getText()+")";
190                        $setText(t);
191                }
192        |       "$set"
193                (       "Text" (WS)? '(' a2:TEXT_ARG ')'
194                        {
195                        String t;
196                        t = "text.Length = _begin; text.Append("+a2.getText()+")";
197                        $setText(t);
198                        }
199                |       "Token" (WS)? '(' a3:TEXT_ARG ')'
200                        {
201                        String t="_token = "+a3.getText();
202                        $setText(t);
203                        }
204                |       "Type" (WS)? '(' a4:TEXT_ARG ')'
205                        {
206                        String t="_ttype = "+a4.getText();
207                        $setText(t);
208                        }
209                )
210        |       "$getText"
211                {
212                        $setText("text.ToString(_begin, text.Length-_begin)");
213                }
214        |       "$FOLLOW" ( (WS)? '(' a5:TEXT_ARG ')' )?
215                {
216                        String rule = currentRule.getRuleName();
217                        if ( a5!=null ) {
218                                rule = a5.getText();
219                        }
220                        String setName = generator.getFOLLOWBitSet(rule, 1);
221                        // System.out.println("FOLLOW("+rule+")="+setName);
222                        if ( setName==null ) {
223                                reportError("$FOLLOW("+rule+")"+
224                                                        ": unknown rule or bad lookahead computation");
225                        }
226                        else {
227                                $setText(setName);
228                        }
229                }
230        |       "$FIRST" ( (WS)? '(' a6:TEXT_ARG ')' )?
231                {
232                        String rule = currentRule.getRuleName();
233                        if ( a6!=null ) {
234                                rule = a6.getText();
235                        }
236                        String setName = generator.getFIRSTBitSet(rule, 1);
237                        // System.out.println("FIRST("+rule+")="+setName);
238                        if ( setName==null ) {
239                                reportError("$FIRST("+rule+")"+
240                                                        ": unknown rule or bad lookahead computation");
241                        }
242                        else {
243                                $setText(setName);
244                        }
245                }
246        ;
247
248protected
249TREE!
250{
251        StringBuffer buf = new StringBuffer();
252        int n=0;
253        Vector terms = new Vector(10);
254}
255        :       '('
256                (WS)?
257                t:TREE_ELEMENT
258                {
259                        terms.appendElement(
260                                generator.processStringForASTConstructor(t.getText())
261                                                                         );
262                }
263                (WS)?
264                (       ','     (WS)?
265                        t2:TREE_ELEMENT
266                        {
267                                terms.appendElement(
268                                        generator.processStringForASTConstructor(t2.getText())
269                                                                                  );
270                        }
271                        (WS)?
272                )*
273                {$setText(generator.getASTCreateString(terms));}
274                ')'
275        ;
276
277protected
278TREE_ELEMENT { boolean was_mapped; }
279        :       '#'! TREE
280        |       '#'! AST_CONSTRUCTOR
281        |       '#'! was_mapped=id:ID_ELEMENT
282                {       // RK: I have a queer feeling that this maptreeid is redundant..
283                        if ( ! was_mapped )
284                        {
285                                String t = generator.mapTreeId(id.getText(), null);
286                                if ( t!=null ) {
287                                        $setText(t);
288                                }
289                        }
290                }
291        |       "##"
292                {
293                        if( currentRule != null )
294                        {
295                                String t = currentRule.getRuleName()+"_AST";
296                                $setText(t);
297                        }
298                        else
299                        {
300                                reportError("\"##\" not valid in this context");
301                                $setText("##");
302                        }
303                }
304        |       TREE
305        |       AST_CONSTRUCTOR
306        |       ID_ELEMENT
307        |       STRING
308        ;
309
310// FIXME: RK - the getASTCreateString here is broken.
311// getASTCreateString can not cleanly see if a constructor like
312// tokens { FOR<AST=ForNode>; }
313// forLoop:! "for" bla bla
314//  { #forLoop = #([FOR,"for"], bla bla ) }
315// should use ForNode as AST.
316//
317protected
318AST_CONSTRUCTOR!
319        :       '[' (WS)? x:AST_CTOR_ELEMENT (WS)?
320                (',' (WS)? y:AST_CTOR_ELEMENT (WS)? )?
321                (',' (WS)? z:AST_CTOR_ELEMENT (WS)? )? ']'
322                {
323                        String args = generator.processStringForASTConstructor(x.getText());
324
325                        // the second does not need processing coz it's a string
326                        // (eg second param of astFactory.create(x,y)
327                        if ( y!=null )
328                                args += ","+y.getText();
329                        if ( z!=null )
330                                args += ","+z.getText();
331
332                        $setText(generator.getASTCreateString(null,args));
333                }
334        ;
335
336/** The arguments of a #[...] constructor are text, token type,
337 *  or a tree.
338 */
339protected
340AST_CTOR_ELEMENT
341        :       STRING
342        |       INT
343        |       TREE_ELEMENT
344        ;
345
346/** An ID_ELEMENT can be a func call, array ref, simple var,
347 *  or AST label ref.
348 */
349protected
350ID_ELEMENT returns [boolean mapped=false]
351        :       id:ID (options {greedy=true;}:WS!)?
352                (       '(' (options {greedy=true;}:WS!)? ( ARG (',' (WS!)? ARG)* )? (WS!)? ')' // method call
353                |       ( '[' (WS!)? ARG (WS!)? ']' )+                          // array reference
354                |       '.' ID_ELEMENT
355                |       "->" ID_ELEMENT
356                |       /* could be a token reference or just a user var */
357                        {
358                                mapped = true;
359                                String t = generator.mapTreeId(id.getText(), transInfo);
360//                              System.out.println("mapped: "+id.getText()+" -> "+t);
361                                if ( t!=null ) {
362                                        $setText(t);
363                                }
364                        }
365                        // if #rule referenced, check for assignment
366                        (       options {greedy=true;}
367                        :       {transInfo!=null && transInfo.refRuleRoot!=null}?
368                                (WS)? VAR_ASSIGN
369                        )?
370                )
371        ;
372
373protected
374TEXT_ARG
375        :       (WS)? ( TEXT_ARG_ELEMENT (options {greedy=true;}:WS)? )+
376        ;
377
378protected
379TEXT_ARG_ELEMENT
380        :       TEXT_ARG_ID_ELEMENT
381        |       STRING
382        |       CHAR
383        |       INT_OR_FLOAT
384        |       TEXT_ITEM
385        |       '+'
386        ;
387
388protected
389TEXT_ARG_ID_ELEMENT
390        :       id:ID (options {greedy=true;}:WS!)?
391                (       '(' (options {greedy=true;}:WS!)? ( TEXT_ARG (',' TEXT_ARG)* )* (WS!)? ')'      // method call
392                |       ( '[' (WS!)? TEXT_ARG (WS!)? ']' )+                             // array reference
393                |       '.' TEXT_ARG_ID_ELEMENT
394                |       "->" TEXT_ARG_ID_ELEMENT
395                |
396                )
397        ;
398
399protected
400ARG     :       (       TREE_ELEMENT
401                |       STRING
402                |       CHAR
403                |       INT_OR_FLOAT
404                )
405                (options {greedy=true;} : (WS)? ( '+'| '-' | '*' | '/' ) (WS)? ARG )*
406        ;
407
408protected
409ID      :       ('a'..'z'|'A'..'Z'|'_')
410                (options {greedy=true;} : ('a'..'z'|'A'..'Z'|'0'..'9'|'_'))*
411        ;
412
413protected
414VAR_ASSIGN
415        :       '='
416                {
417                        // inform the code generator that an assignment was done to
418                        // AST root for the rule if invoker set refRuleRoot.
419                        if ( LA(1)!='=' && transInfo!=null && transInfo.refRuleRoot!=null ) {
420                                transInfo.assignToRoot=true;
421                        }
422                }
423        ;
424
425protected
426COMMENT
427        :       SL_COMMENT
428        |       ML_COMMENT
429        ;
430
431protected
432SL_COMMENT
433        :       "//" (options {greedy=false;}:.)* ('\n'|"\r\n"|'\r')
434                {newline();}
435        ;
436
437protected
438ML_COMMENT :
439        "/*"
440        (       options {greedy=false;}
441        :       '\r' '\n'       {newline();}
442        |       '\r'            {newline();}
443        |       '\n'            {newline();}
444        |       .
445        )*
446        "*/"
447        ;
448
449protected
450CHAR :
451        '\''
452        ( ESC | ~'\'' )
453        '\''
454        ;
455
456protected
457STRING :
458        '"'
459        (ESC|~'"')*
460        '"'
461        ;
462
463protected
464ESC     :       '\\'
465                (       'n'
466                |       'r'
467                |       't'
468                |       'b'
469                |       'f'
470                |       '"'
471                |       '\''
472                |       '\\'
473                |       ('0'..'3')
474                        (       options {greedy=true;}
475                        :       DIGIT
476                                (       options {greedy=true;}
477                                :       DIGIT
478                                )?
479                        )?
480                |       ('4'..'7') (options {greedy=true;}:DIGIT)?
481                )
482        ;
483
484protected
485DIGIT
486        :       '0'..'9'
487        ;
488
489protected
490INT     :       (DIGIT)+
491        ;
492
493protected
494INT_OR_FLOAT
495        :       (options {greedy=true;}:DIGIT)+
496                (       options {greedy=true;}
497                :       '.' (options {greedy=true;}:DIGIT)*
498                |       'L'
499                |       'l'
500                )?
501        ;
502
503protected
504WS      :       (       options {greedy=true;}
505                :       ' '
506                |       '\t'
507                |       '\r' '\n'       {newline();}
508                |       '\r'            {newline();}
509                |       '\n'            {newline();}
510                )+
511        ;
Note: See TracBrowser for help on using the repository browser.