| 376 | } |
| 377 | |
| 378 | Token subTemplate() { |
| 379 | // look for "{ args ID (',' ID)* '|' ..." |
| 380 | subtemplateDepth++; |
| 381 | int m = input.mark(); |
| 382 | int curlyStartChar = startCharIndex; |
| 383 | int curlyLine = startLine; |
| 384 | int curlyPos = startCharPositionInLine; |
| 385 | List<Token> argTokens = new ArrayList<Token>(); |
| 386 | consume(); |
| 387 | Token curly = newTokenFromPreviousChar(LCURLY); |
| 388 | WS(); |
| 389 | argTokens.add(mID()); |
| 390 | WS(); |
| 391 | while ( c==',' ) { |
| 392 | consume(); |
| 393 | argTokens.add(newTokenFromPreviousChar(COMMA)); |
| 394 | WS(); |
| 395 | argTokens.add(mID()); |
| 396 | WS(); |
| 397 | } |
| 398 | WS(); |
| 399 | if ( c=='|' ) { |
| 400 | consume(); |
| 401 | argTokens.add(newTokenFromPreviousChar(PIPE)); |
| 402 | if ( isWS(c) ) consume(); // ignore a single whitespace after | |
| 403 | //System.out.println("matched args: "+argTokens); |
| 404 | for (Token t : argTokens) emit(t); |
| 405 | input.release(m); |
| 406 | scanningInsideExpr = false; |
| 407 | startCharIndex = curlyStartChar; // reset state |
| 408 | startLine = curlyLine; |
| 409 | startCharPositionInLine = curlyPos; |
| 410 | return curly; |
| 411 | } |
| 412 | input.rewind(m); |
| 413 | startCharIndex = curlyStartChar; // reset state |
| 414 | startLine = curlyLine; |
| 415 | startCharPositionInLine = curlyPos; |
| 416 | consume(); |
| 417 | scanningInsideExpr = false; |
| 418 | return curly; |
| 419 | } |
| 420 | |
| 421 | Token ESCAPE() { |
| 422 | startCharIndex = input.index(); |