1 package org.codehaus.groovy.syntax.lexer; 2 3 import org.codehaus.groovy.syntax.ReadException; 5 import org.codehaus.groovy.syntax.Types; 6 import org.codehaus.groovy.syntax.Token; 7 9 14 15 public class GStringLexer extends LexerBase 16 { 17 18 protected boolean sentStartToken = false; 19 protected boolean sentEndToken = false; 20 21 protected StringBuffer fullText = new StringBuffer (); 22 protected int fullTextStartLine = 0; 23 protected int fullTextStartColumn = 0; 24 25 protected GroovyExpressionLexer child = null; 26 protected boolean inExpression = false; 27 28 29 33 34 protected Token undelegatedNextToken() throws ReadException, LexerException 35 { 36 Token token = null; 38 39 40 43 if( !sentStartToken ) 44 { 45 mark(); 46 fullTextStartLine = getStartLine(); 47 fullTextStartColumn = getStartColumn(); 48 sentStartToken = true; 49 50 return symbol( Types.GSTRING_START ); 52 } 53 else if( la(1) == CharStream.EOS ) 54 { 55 if( !sentEndToken ) 56 { 57 sentEndToken = true; 58 token = Token.newSymbol( Types.GSTRING_END, fullTextStartLine, fullTextStartColumn ); 59 token.setText( fullText.toString() ); 60 } 61 62 return token; 64 } 65 66 67 72 if( inExpression && la(1) != '}' ) 73 { 74 mark(); 75 unexpected( la(1), 0 ); 76 } 77 78 79 82 mark(); 83 StringBuffer segment = new StringBuffer (); 84 85 char c; 86 MAIN_LOOP: while( true ) 87 { 88 c = la(1); 89 90 ROOT_SWITCH: switch( c ) 91 { 92 case CharStream.EOS: 93 { 94 break MAIN_LOOP; 95 } 96 97 case '\r': 98 case '\n': 99 { 100 readEOL( segment ); 101 break ROOT_SWITCH; 102 } 103 104 case '\\': 105 { 106 ESCAPE_SWITCH: switch( la(2) ) 107 { 108 case '\\': 109 case '$': 110 { 111 consume(); 112 segment.append( consume() ); 113 break ESCAPE_SWITCH; 114 } 115 116 default: 117 { 118 segment.append( consume() ); 119 break ESCAPE_SWITCH; 120 } 121 } 122 123 break ROOT_SWITCH; 124 } 125 126 case '$': 127 { 128 if( la(2) == '{' ) 129 { 130 if( segment.length() == 0 ) 131 { 132 sourceDelimiting( false ); 134 mark(); 135 consume(); 136 consume(); 137 138 token = symbol( Types.GSTRING_EXPRESSION_START ); 139 inExpression = true; 140 141 if( child == null ) 142 { 143 child = new GroovyExpressionLexer(); 144 } 145 else 146 { 147 child.reset(); 148 } 149 150 delegate( child ); 151 152 break MAIN_LOOP; 153 } 154 else 155 { 156 break MAIN_LOOP; 157 } 158 } 159 else 160 { 161 segment.append( consume() ); 162 } 163 164 break ROOT_SWITCH; 165 } 166 167 case '}': 168 { 169 if( inExpression ) 170 { 171 mark(); 172 consume(); 173 token = symbol( Types.GSTRING_EXPRESSION_END ); 174 175 inExpression = false; 176 177 break MAIN_LOOP; 178 } 179 else 180 { 181 segment.append( consume() ); 182 break ROOT_SWITCH; 183 } 184 } 185 186 default: 187 { 188 segment.append( consume() ); 189 break ROOT_SWITCH; 190 } 191 } 192 } 193 194 195 if( token != null ) 196 { 197 return token; 199 } 200 else 201 { 202 return Token.newString( segment.toString(), getStartLine(), getStartColumn() ); 204 } 205 206 } 207 208 209 210 211 214 215 220 221 protected void sourceDelimiting( boolean delimit ) 222 { 223 if( source instanceof Delimiter ) 224 { 225 ((Delimiter)source).delimit( delimit ); 226 } 227 } 228 229 230 231 234 235 public void delegate( Lexer to ) 236 { 237 this.delegate = to; 238 sourceDelimiting( false ); 239 to.setSource( this ); 240 } 241 242 243 244 247 248 public void undelegate() 249 { 250 if( delegate != null ) 251 { 252 delegate.unsetSource( ); 253 delegate = null; 254 sourceDelimiting( true ); 255 } 256 } 257 258 259 260 263 264 public void setSource( Lexer source ) 265 { 266 super.setSource( source ); 267 268 sentStartToken = false; 269 sentEndToken = false; 270 271 fullTextStartLine = getStartLine(); 272 fullTextStartColumn = getStartColumn(); 273 fullText = new StringBuffer (); 274 275 inExpression = false; 276 } 277 278 279 280 283 284 public void unsetSource() 285 { 286 super.unsetSource(); 287 288 sentStartToken = false; 289 sentEndToken = false; 290 fullText = null; 291 inExpression = false; 292 } 293 294 295 296 297 300 301 304 305 public char consume() throws LexerException, ReadException 306 { 307 char c = super.consume(); 308 309 if( c != CharStream.EOS ) 310 { 311 fullText.append(c); 312 } 313 314 return c; 315 } 316 317 318 } 319 320 | Popular Tags |