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
33namespace 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
64        public TreePatternLexer( string pattern )
65        {
66            this.pattern = pattern;
67            this.n = pattern.Length;
68            Consume();
69        }
70
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
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