aboutsummaryrefslogtreecommitdiff
path: root/runtime/CSharp3/Sources/Antlr3.Runtime/RecognizerSharedState.cs
blob: 2b7c6cf5bcf5feb966959a887c2693f7c50f46d5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
/*
 * [The "BSD licence"]
 * Copyright (c) 2005-2008 Terence Parr
 * All rights reserved.
 *
 * Conversion to C#:
 * Copyright (c) 2008-2009 Sam Harwell, Pixel Mine, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

namespace Antlr.Runtime
{
    using System.Collections.Generic;
    using CLSCompliant = System.CLSCompliantAttribute;
    using ArgumentNullException = System.ArgumentNullException;

    /** <summary>
     *  The set of fields needed by an abstract recognizer to recognize input
     *  and recover from errors etc...  As a separate state object, it can be
     *  shared among multiple grammars; e.g., when one grammar imports another.
     *  </summary>
     *
     *  <remarks>
     *  These fields are publically visible but the actual state pointer per
     *  parser is protected.
     *  </remarks>
     */
    public class RecognizerSharedState
    {
        /** <summary>
         *  Track the set of token types that can follow any rule invocation.
         *  Stack grows upwards.  When it hits the max, it grows 2x in size
         *  and keeps going.
         *  </summary>
         */
        //public List<BitSet> following;
        public BitSet[] following;
        [CLSCompliant( false )]
        public int _fsp;

        /** <summary>
         *  This is true when we see an error and before having successfully
         *  matched a token.  Prevents generation of more than one error message
         *  per error.
         *  </summary>
         */
        public bool errorRecovery;

        /** <summary>
         *  The index into the input stream where the last error occurred.
         * 	This is used to prevent infinite loops where an error is found
         *  but no token is consumed during recovery...another error is found,
         *  ad naseum.  This is a failsafe mechanism to guarantee that at least
         *  one token/tree node is consumed for two errors.
         *  </summary>
         */
        public int lastErrorIndex;

        /** <summary>
         *  In lieu of a return value, this indicates that a rule or token
         *  has failed to match.  Reset to false upon valid token match.
         *  </summary>
         */
        public bool failed;

        /** <summary>Did the recognizer encounter a syntax error?  Track how many.</summary> */
        public int syntaxErrors;

        /** <summary>
         *  If 0, no backtracking is going on.  Safe to exec actions etc...
         *  If >0 then it's the level of backtracking.
         *  </summary>
         */
        public int backtracking;

        /** <summary>
         *  An array[size num rules] of Map<Integer,Integer> that tracks
         *  the stop token index for each rule.  ruleMemo[ruleIndex] is
         *  the memoization table for ruleIndex.  For key ruleStartIndex, you
         *  get back the stop token for associated rule or MEMO_RULE_FAILED.
         *  </summary>
         *
         *  <remarks>This is only used if rule memoization is on (which it is by default).</remarks>
         */
        public IDictionary<int, int>[] ruleMemo;


        // LEXER FIELDS (must be in same state object to avoid casting
        //               constantly in generated code and Lexer object) :(


        /** <summary>
         *  The goal of all lexer rules/methods is to create a token object.
         *  This is an instance variable as multiple rules may collaborate to
         *  create a single token.  nextToken will return this object after
         *  matching lexer rule(s).  If you subclass to allow multiple token
         *  emissions, then set this to the last token to be matched or
         *  something nonnull so that the auto token emit mechanism will not
         *  emit another token.
         *  </summary>
         */
        public IToken token;

        /** <summary>
         *  What character index in the stream did the current token start at?
         *  Needed, for example, to get the text for current token.  Set at
         *  the start of nextToken.
         *  </summary>
         */
        public int tokenStartCharIndex;

        /** <summary>The line on which the first character of the token resides</summary> */
        public int tokenStartLine;

        /** <summary>The character position of first character within the line</summary> */
        public int tokenStartCharPositionInLine;

        /** <summary>The channel number for the current token</summary> */
        public int channel;

        /** <summary>The token type for the current token</summary> */
        public int type;

        /** <summary>
         *  You can set the text for the current token to override what is in
         *  the input char buffer.  Use setText() or can set this instance var.
         *  </summary>
         */
        public string text;

        public RecognizerSharedState()
        {
            //following = new List<BitSet>( BaseRecognizer.InitialFollowStackSize );
            following = new BitSet[BaseRecognizer.InitialFollowStackSize];
            _fsp = -1;
            lastErrorIndex = -1;
            tokenStartCharIndex = -1;
        }

        public RecognizerSharedState( RecognizerSharedState state )
        {
            if (state == null)
                throw new ArgumentNullException("state");

            following = (BitSet[])state.following.Clone();
            _fsp = state._fsp;
            errorRecovery = state.errorRecovery;
            lastErrorIndex = state.lastErrorIndex;
            failed = state.failed;
            syntaxErrors = state.syntaxErrors;
            backtracking = state.backtracking;

            if ( state.ruleMemo != null )
                ruleMemo = (IDictionary<int, int>[])state.ruleMemo.Clone();

            token = state.token;
            tokenStartCharIndex = state.tokenStartCharIndex;
            tokenStartCharPositionInLine = state.tokenStartCharPositionInLine;
            channel = state.channel;
            type = state.type;
            text = state.text;
        }
    }
}