| /* |
| * [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.Tree |
| { |
| using ConditionalAttribute = System.Diagnostics.ConditionalAttribute; |
| using Regex = System.Text.RegularExpressions.Regex; |
| using RegexOptions = System.Text.RegularExpressions.RegexOptions; |
| |
| /** <summary> |
| * A parser for a stream of tree nodes. "tree grammars" result in a subclass |
| * of this. All the error reporting and recovery is shared with Parser via |
| * the BaseRecognizer superclass. |
| * </summary> |
| */ |
| public class TreeParser : BaseRecognizer |
| { |
| public const int DOWN = TokenTypes.Down; |
| public const int UP = TokenTypes.Up; |
| |
| // precompiled regex used by inContext |
| static string dotdot = ".*[^.]\\.\\.[^.].*"; |
| static string doubleEtc = ".*\\.\\.\\.\\s+\\.\\.\\..*"; |
| static Regex dotdotPattern = new Regex( dotdot, RegexOptions.Compiled ); |
| static Regex doubleEtcPattern = new Regex( doubleEtc, RegexOptions.Compiled ); |
| |
| protected ITreeNodeStream input; |
| |
| public TreeParser( ITreeNodeStream input ) |
| : base() // highlight that we go to super to set state object |
| { |
| SetTreeNodeStream( input ); |
| } |
| |
| public TreeParser( ITreeNodeStream input, RecognizerSharedState state ) |
| : base( state ) // share the state object with another parser |
| { |
| SetTreeNodeStream( input ); |
| } |
| |
| public override void Reset() |
| { |
| base.Reset(); // reset all recognizer state variables |
| if ( input != null ) |
| { |
| input.Seek( 0 ); // rewind the input |
| } |
| } |
| |
| /** <summary>Set the input stream</summary> */ |
| public virtual void SetTreeNodeStream( ITreeNodeStream input ) |
| { |
| this.input = input; |
| } |
| |
| public virtual ITreeNodeStream GetTreeNodeStream() |
| { |
| return input; |
| } |
| |
| public override string SourceName |
| { |
| get |
| { |
| return input.SourceName; |
| } |
| } |
| |
| protected override object GetCurrentInputSymbol( IIntStream input ) |
| { |
| return ( (ITreeNodeStream)input ).LT( 1 ); |
| } |
| |
| protected override object GetMissingSymbol( IIntStream input, |
| RecognitionException e, |
| int expectedTokenType, |
| BitSet follow ) |
| { |
| string tokenText = |
| "<missing " + TokenNames[expectedTokenType] + ">"; |
| ITreeAdaptor adaptor = ((ITreeNodeStream)e.Input).TreeAdaptor; |
| return adaptor.Create(new CommonToken(expectedTokenType, tokenText)); |
| } |
| |
| /** <summary> |
| * Match '.' in tree parser has special meaning. Skip node or |
| * entire tree if node has children. If children, scan until |
| * corresponding UP node. |
| * </summary> |
| */ |
| public override void MatchAny( IIntStream ignore ) |
| { |
| state.errorRecovery = false; |
| state.failed = false; |
| // always consume the current node |
| input.Consume(); |
| // if the next node is DOWN, then the current node is a subtree: |
| // skip to corresponding UP. must count nesting level to get right UP |
| int look = input.LA( 1 ); |
| if ( look == DOWN ) |
| { |
| input.Consume(); |
| int level = 1; |
| while ( level > 0 ) |
| { |
| switch ( input.LA( 1 ) ) |
| { |
| case DOWN: |
| level++; |
| break; |
| case UP: |
| level--; |
| break; |
| case TokenTypes.EndOfFile: |
| return; |
| default: |
| break; |
| } |
| input.Consume(); |
| } |
| } |
| } |
| |
| /** <summary> |
| * We have DOWN/UP nodes in the stream that have no line info; override. |
| * plus we want to alter the exception type. Don't try to recover |
| * from tree parser errors inline... |
| * </summary> |
| */ |
| protected override object RecoverFromMismatchedToken( IIntStream input, int ttype, BitSet follow ) |
| { |
| throw new MismatchedTreeNodeException( ttype, (ITreeNodeStream)input ); |
| } |
| |
| /** <summary> |
| * Prefix error message with the grammar name because message is |
| * always intended for the programmer because the parser built |
| * the input tree not the user. |
| * </summary> |
| */ |
| public override string GetErrorHeader( RecognitionException e ) |
| { |
| return GrammarFileName + ": node from " + |
| ( e.ApproximateLineInfo ? "after " : "" ) + "line " + e.Line + ":" + e.CharPositionInLine; |
| } |
| |
| /** <summary> |
| * Tree parsers parse nodes they usually have a token object as |
| * payload. Set the exception token and do the default behavior. |
| * </summary> |
| */ |
| public override string GetErrorMessage( RecognitionException e, string[] tokenNames ) |
| { |
| if ( this is TreeParser ) |
| { |
| ITreeAdaptor adaptor = ( (ITreeNodeStream)e.Input ).TreeAdaptor; |
| e.Token = adaptor.GetToken( e.Node ); |
| if ( e.Token == null ) |
| { // could be an UP/DOWN node |
| e.Token = new CommonToken( adaptor.GetType( e.Node ), |
| adaptor.GetText( e.Node ) ); |
| } |
| } |
| return base.GetErrorMessage( e, tokenNames ); |
| } |
| |
| [Conditional("ANTLR_TRACE")] |
| public virtual void TraceIn( string ruleName, int ruleIndex ) |
| { |
| base.TraceIn( ruleName, ruleIndex, input.LT( 1 ) ); |
| } |
| |
| [Conditional("ANTLR_TRACE")] |
| public virtual void TraceOut( string ruleName, int ruleIndex ) |
| { |
| base.TraceOut( ruleName, ruleIndex, input.LT( 1 ) ); |
| } |
| |
| } |
| } |