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