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 InvalidOperationException = System.InvalidOperationException; 36 37 public class TreePatternParser 38 { 39 protected TreePatternLexer tokenizer; 40 protected int ttype; 41 protected TreeWizard wizard; 42 protected ITreeAdaptor adaptor; 43 TreePatternParser( TreePatternLexer tokenizer, TreeWizard wizard, ITreeAdaptor adaptor )44 public TreePatternParser( TreePatternLexer tokenizer, TreeWizard wizard, ITreeAdaptor adaptor ) 45 { 46 this.tokenizer = tokenizer; 47 this.wizard = wizard; 48 this.adaptor = adaptor; 49 ttype = tokenizer.NextToken(); // kickstart 50 } 51 Pattern()52 public virtual object Pattern() 53 { 54 if ( ttype == TreePatternLexer.Begin ) 55 { 56 return ParseTree(); 57 } 58 else if ( ttype == TreePatternLexer.Id ) 59 { 60 object node = ParseNode(); 61 if ( ttype == CharStreamConstants.EndOfFile ) 62 { 63 return node; 64 } 65 return null; // extra junk on end 66 } 67 return null; 68 } 69 ParseTree()70 public virtual object ParseTree() 71 { 72 if ( ttype != TreePatternLexer.Begin ) 73 throw new InvalidOperationException("No beginning."); 74 75 ttype = tokenizer.NextToken(); 76 object root = ParseNode(); 77 if ( root == null ) 78 { 79 return null; 80 } 81 while ( ttype == TreePatternLexer.Begin || 82 ttype == TreePatternLexer.Id || 83 ttype == TreePatternLexer.Percent || 84 ttype == TreePatternLexer.Dot ) 85 { 86 if ( ttype == TreePatternLexer.Begin ) 87 { 88 object subtree = ParseTree(); 89 adaptor.AddChild( root, subtree ); 90 } 91 else 92 { 93 object child = ParseNode(); 94 if ( child == null ) 95 { 96 return null; 97 } 98 adaptor.AddChild( root, child ); 99 } 100 } 101 102 if ( ttype != TreePatternLexer.End ) 103 throw new InvalidOperationException("No end."); 104 105 ttype = tokenizer.NextToken(); 106 return root; 107 } 108 ParseNode()109 public virtual object ParseNode() 110 { 111 // "%label:" prefix 112 string label = null; 113 if ( ttype == TreePatternLexer.Percent ) 114 { 115 ttype = tokenizer.NextToken(); 116 if ( ttype != TreePatternLexer.Id ) 117 { 118 return null; 119 } 120 label = tokenizer.sval.ToString(); 121 ttype = tokenizer.NextToken(); 122 if ( ttype != TreePatternLexer.Colon ) 123 { 124 return null; 125 } 126 ttype = tokenizer.NextToken(); // move to ID following colon 127 } 128 129 // Wildcard? 130 if ( ttype == TreePatternLexer.Dot ) 131 { 132 ttype = tokenizer.NextToken(); 133 IToken wildcardPayload = new CommonToken( 0, "." ); 134 TreeWizard.TreePattern node = 135 new TreeWizard.WildcardTreePattern( wildcardPayload ); 136 if ( label != null ) 137 { 138 node.label = label; 139 } 140 return node; 141 } 142 143 // "ID" or "ID[arg]" 144 if ( ttype != TreePatternLexer.Id ) 145 { 146 return null; 147 } 148 string tokenName = tokenizer.sval.ToString(); 149 ttype = tokenizer.NextToken(); 150 if ( tokenName.Equals( "nil" ) ) 151 { 152 return adaptor.Nil(); 153 } 154 string text = tokenName; 155 // check for arg 156 string arg = null; 157 if ( ttype == TreePatternLexer.Arg ) 158 { 159 arg = tokenizer.sval.ToString(); 160 text = arg; 161 ttype = tokenizer.NextToken(); 162 } 163 164 // create node 165 int treeNodeType = wizard.GetTokenType( tokenName ); 166 if ( treeNodeType == TokenTypes.Invalid ) 167 { 168 return null; 169 } 170 object node2; 171 node2 = adaptor.Create( treeNodeType, text ); 172 if ( label != null && node2.GetType() == typeof( TreeWizard.TreePattern ) ) 173 { 174 ( (TreeWizard.TreePattern)node2 ).label = label; 175 } 176 if ( arg != null && node2.GetType() == typeof( TreeWizard.TreePattern ) ) 177 { 178 ( (TreeWizard.TreePattern)node2 ).hasTextArg = true; 179 } 180 return node2; 181 } 182 } 183 } 184