1 /*
2  * [The "BSD licence"]
3  * Copyright (c) 2005-2008 Terence Parr
4  * All rights reserved.
5  *
6  * Conversion to C#:
7  * Copyright (c) 2008-2009 Sam Harwell, Pixel Mine, Inc.
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. The name of the author may not be used to endorse or promote products
19  *    derived from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 namespace Antlr.Runtime.Tree
34 {
35     using StringBuilder = System.Text.StringBuilder;
36 
37     public class TreePatternLexer
38     {
39         public const int Begin = 1;
40         public const int End = 2;
41         public const int Id = 3;
42         public const int Arg = 4;
43         public const int Percent = 5;
44         public const int Colon = 6;
45         public const int Dot = 7;
46 
47         /** <summary>The tree pattern to lex like "(A B C)"</summary> */
48         protected string pattern;
49 
50         /** <summary>Index into input string</summary> */
51         protected int p = -1;
52 
53         /** <summary>Current char</summary> */
54         protected int c;
55 
56         /** <summary>How long is the pattern in char?</summary> */
57         protected int n;
58 
59         /** <summary>Set when token type is ID or ARG (name mimics Java's StreamTokenizer)</summary> */
60         public StringBuilder sval = new StringBuilder();
61 
62         public bool error = false;
63 
TreePatternLexer( string pattern )64         public TreePatternLexer( string pattern )
65         {
66             this.pattern = pattern;
67             this.n = pattern.Length;
68             Consume();
69         }
70 
NextToken()71         public virtual int NextToken()
72         {
73             sval.Length = 0; // reset, but reuse buffer
74             while ( c != CharStreamConstants.EndOfFile )
75             {
76                 if ( c == ' ' || c == '\n' || c == '\r' || c == '\t' )
77                 {
78                     Consume();
79                     continue;
80                 }
81                 if ( ( c >= 'a' && c <= 'z' ) || ( c >= 'A' && c <= 'Z' ) || c == '_' )
82                 {
83                     sval.Append( (char)c );
84                     Consume();
85                     while ( ( c >= 'a' && c <= 'z' ) || ( c >= 'A' && c <= 'Z' ) ||
86                             ( c >= '0' && c <= '9' ) || c == '_' )
87                     {
88                         sval.Append( (char)c );
89                         Consume();
90                     }
91                     return Id;
92                 }
93                 if ( c == '(' )
94                 {
95                     Consume();
96                     return Begin;
97                 }
98                 if ( c == ')' )
99                 {
100                     Consume();
101                     return End;
102                 }
103                 if ( c == '%' )
104                 {
105                     Consume();
106                     return Percent;
107                 }
108                 if ( c == ':' )
109                 {
110                     Consume();
111                     return Colon;
112                 }
113                 if ( c == '.' )
114                 {
115                     Consume();
116                     return Dot;
117                 }
118                 if ( c == '[' )
119                 {
120                     // grab [x] as a string, returning x
121                     Consume();
122                     while ( c != ']' )
123                     {
124                         if ( c == '\\' )
125                         {
126                             Consume();
127                             if ( c != ']' )
128                             {
129                                 sval.Append( '\\' );
130                             }
131                             sval.Append( (char)c );
132                         }
133                         else
134                         {
135                             sval.Append( (char)c );
136                         }
137                         Consume();
138                     }
139                     Consume();
140                     return Arg;
141                 }
142                 Consume();
143                 error = true;
144                 return CharStreamConstants.EndOfFile;
145             }
146             return CharStreamConstants.EndOfFile;
147         }
148 
Consume()149         protected virtual void Consume()
150         {
151             p++;
152             if ( p >= n )
153             {
154                 c = CharStreamConstants.EndOfFile;
155             }
156             else
157             {
158                 c = pattern[p];
159             }
160         }
161     }
162 }
163