antlr.g
上传用户:afrynkmhm
上传日期:2007-01-06
资源大小:1262k
文件大小:20k
源码类别:

编译器/解释器

开发平台:

Others

  1. header {
  2. package antlr;
  3. }
  4. {
  5. import java.util.Enumeration;
  6. import java.io.DataInputStream;
  7. import java.io.InputStream;
  8. import java.io.FileInputStream;
  9. import java.io.IOException;
  10. }
  11. /* ANTLR Translator Generator
  12.  * Project led by Terence Parr at http://www.jGuru.com
  13.  * Software rights: http://www.antlr.org/RIGHTS.html
  14.  *
  15.  * $Id: //depot/code/org.antlr/release/antlr-2.7.0/antlr/antlr.g#1 $
  16.  */
  17. class ANTLRParser extends Parser;
  18. options {
  19. exportVocab=ANTLR;
  20. defaultErrorHandler=false;
  21. k=2;
  22. }
  23. tokens {
  24. "tokens";
  25. }
  26. {
  27. private static final boolean DEBUG_PARSER = false;
  28. ANTLRGrammarParseBehavior behavior;
  29. Tool tool;
  30. protected int blockNesting= -1;
  31. public ANTLRParser(
  32. TokenBuffer tokenBuf, 
  33. ANTLRGrammarParseBehavior behavior_,
  34. Tool tool_
  35. ) {
  36. super(tokenBuf, 1);
  37. tokenNames = _tokenNames;
  38. behavior = behavior_;
  39. tool = tool_;
  40. }
  41. private boolean lastInRule() throws TokenStreamException {
  42. if ( blockNesting==0 && (LA(1)==SEMI || LA(1)==LITERAL_exception || LA(1)==OR) ) {
  43. return true;
  44. }
  45. return false;
  46. }
  47. }
  48. grammar
  49.    :
  50. ( "header" (n:STRING_LITERAL)? h:ACTION {behavior.refHeaderAction(n,h);} )*
  51. ( fileOptionsSpec )?
  52. ( classDef )*
  53. EOF
  54. ;
  55. exception catch [RecognitionException ex] {
  56. reportError("rule grammar trapped: "+ex.toString());
  57. consumeUntil(EOF);
  58. }
  59. classDef
  60. {String doc=null;}
  61. :
  62. ( a:ACTION { behavior.refPreambleAction(a);} )?
  63. ( d:DOC_COMMENT {doc=d.getText();} )?
  64. ( ("lexclass" | "class" id "extends" "Lexer" ) => lexerSpec[doc]
  65. | ( "class" id "extends" "TreeParser" ) => treeParserSpec[doc]
  66. | parserSpec[doc]
  67. )
  68. rules
  69. { behavior.endGrammar(); }
  70. ;
  71. exception catch [RecognitionException ex] {
  72. if ( ex instanceof NoViableAltException ) {
  73. NoViableAltException e = (NoViableAltException)ex;
  74. if ( e.token.getType()==DOC_COMMENT ) {
  75. reportError("line "+ex.line+": JAVADOC comments may only prefix rules and grammars");
  76. }
  77. else {
  78. reportError("rule classDef trapped: "+ex.toString());
  79. }
  80. }
  81. else {
  82. reportError("rule classDef trapped: "+ex.toString());
  83. }
  84. behavior.abortGrammar();
  85. boolean consuming = true;
  86. // consume everything until the next class definition or EOF
  87. while (consuming) {
  88. consume();
  89. switch(LA(1)) {
  90. case LITERAL_class:
  91. case LITERAL_lexclass:
  92. case EOF:
  93. consuming = false;
  94. break;
  95. }
  96. }
  97. }
  98. fileOptionsSpec 
  99. { Token idTok; Token value; }
  100. : OPTIONS
  101. (
  102. idTok = id
  103. ASSIGN
  104. value = optionValue
  105. { behavior.setFileOption(idTok, value,getInputState().filename); }
  106. SEMI
  107. )*
  108. RCURLY
  109. ;
  110. parserOptionsSpec 
  111. { Token idTok; Token value; }
  112. : OPTIONS
  113. (
  114. idTok = id
  115. ASSIGN
  116. value = optionValue
  117. { behavior.setGrammarOption(idTok, value); }
  118. SEMI
  119. )*
  120. RCURLY
  121. ;
  122. treeParserOptionsSpec 
  123. { Token idTok; Token value; }
  124. : OPTIONS
  125. (
  126. idTok = id
  127. ASSIGN
  128. value = optionValue
  129. { behavior.setGrammarOption(idTok, value); }
  130. SEMI
  131. )*
  132. RCURLY
  133. ;
  134. lexerOptionsSpec
  135. { Token idTok; Token value; BitSet b; }
  136. :
  137. OPTIONS
  138. ( // Special case for vocabulary option because it has a bit-set
  139. "charVocabulary" 
  140. ASSIGN 
  141. b = charSet
  142. SEMI
  143. { behavior.setCharVocabulary(b); }
  144. | idTok = id
  145. ASSIGN
  146. value = optionValue
  147. { behavior.setGrammarOption(idTok, value); }
  148. SEMI
  149. )*
  150. RCURLY
  151. ;
  152. subruleOptionsSpec
  153. { Token idTok; Token value; }
  154. : OPTIONS
  155. ( idTok = id
  156. ASSIGN
  157. value = optionValue
  158. { behavior.setSubruleOption(idTok, value); }
  159. SEMI
  160. )*
  161. RCURLY
  162. ;
  163. // optionValue returns a Token which may be one of several things:
  164. //    STRING_LITERAL -- a quoted string
  165. //    CHAR_LITERAL -- a single quoted character
  166. // INT -- an integer
  167. // RULE_REF or TOKEN_REF -- an identifier
  168. optionValue 
  169. returns [ Token retval ]
  170. { retval = null; }
  171. : retval = qualifiedID
  172. | sl:STRING_LITERAL { retval = sl; }
  173. | cl:CHAR_LITERAL { retval = cl; }
  174. | il:INT { retval = il; }
  175. ;
  176. charSet
  177. returns [ BitSet b ]
  178. b = null; 
  179. BitSet tmpSet = null;
  180. }
  181. :
  182. // TODO: generate a bit set
  183. b = setBlockElement
  184. (
  185. OR 
  186. tmpSet = setBlockElement
  187. { b.orInPlace(tmpSet); }
  188. )* 
  189. ;
  190. setBlockElement
  191. returns [ BitSet b ]
  192. {
  193. b = null;
  194. int rangeMin = 0; 
  195. }
  196. :
  197. c1:CHAR_LITERAL
  198. rangeMin = ANTLRLexer.tokenTypeForCharLiteral(c1.getText()); 
  199. b = BitSet.of(rangeMin);
  200. }
  201. (
  202. RANGE c2:CHAR_LITERAL
  203. int rangeMax = ANTLRLexer.tokenTypeForCharLiteral(c2.getText()); 
  204. if (rangeMax < rangeMin) {
  205. tool.error("Malformed range line "+c1.getLine());
  206. }
  207. for (int i = rangeMin+1; i <= rangeMax; i++) {
  208. b.add(i);
  209. }
  210. }
  211. )?
  212. ;
  213. tokensSpec
  214. : TOKENS
  215. ( ( {s1=null;}
  216. t1:TOKEN_REF
  217. ( ASSIGN s1:STRING_LITERAL )?
  218. {behavior.defineToken(t1, s1);}
  219. (tokensSpecOptions[t1])?
  220. | s3:STRING_LITERAL
  221. {behavior.defineToken(null, s3);}
  222. (tokensSpecOptions[s3])?
  223. )
  224. SEMI
  225. )+
  226. RCURLY
  227. ;
  228. tokensSpecOptions[Token t]
  229. {
  230. Token o=null, v=null;
  231. }
  232. : OPEN_ELEMENT_OPTION
  233. o=id ASSIGN v=optionValue
  234. {behavior.refTokensSpecElementOption(t,o,v);}
  235. (
  236. SEMI
  237. o=id ASSIGN v=optionValue
  238. {behavior.refTokensSpecElementOption(t,o,v);}
  239. )*
  240. CLOSE_ELEMENT_OPTION
  241. ;
  242. superClass returns [String sup]
  243. {sup=null;}
  244. : LPAREN
  245. {sup = LT(1).getText();}
  246. (TOKEN_REF|RULE_REF)
  247. RPAREN
  248. ;
  249. parserSpec[String doc]
  250. {
  251. Token idTok;
  252. String sup=null;
  253. }
  254. : "class" 
  255. idTok = id
  256. ( "extends" "Parser"
  257. (sup=superClass)?
  258. | {
  259. System.out.println("warning: line " +
  260. idTok.getLine() + ": use 'class X extends Parser'");
  261. }
  262. )
  263. {behavior.startParser(getFilename(), idTok, sup, doc);}
  264. SEMI
  265. (parserOptionsSpec)?
  266. { behavior.endOptions(); }
  267. (tokensSpec)?
  268. ( a:ACTION {behavior.refMemberAction(a);} )?
  269. ;
  270. lexerSpec[String doc]
  271. {
  272. Token idTok;
  273. String sup=null;
  274. }
  275. :   ( lc:"lexclass"
  276. idTok = id
  277. { System.out.println("warning: line " + lc.getLine() + ": 'lexclass' is deprecated; use 'class X extends Lexer'"); }
  278. | "class"
  279. idTok = id
  280. "extends"
  281. "Lexer"
  282. (sup=superClass)?
  283. )
  284. {behavior.startLexer(getFilename(), idTok,sup,doc);}
  285. SEMI
  286. (lexerOptionsSpec)?
  287. { behavior.endOptions(); }
  288. (tokensSpec)?
  289. ( a:ACTION {behavior.refMemberAction(a);} )?
  290. ;
  291. treeParserSpec[String doc]
  292. {
  293. Token idTok;
  294. String sup=null;
  295. }
  296. : "class"
  297. idTok = id
  298. "extends"
  299. "TreeParser"
  300. (sup=superClass)?
  301. {behavior.startTreeWalker(getFilename(), idTok,sup,doc);}
  302. SEMI
  303. (treeParserOptionsSpec)?
  304. { behavior.endOptions(); }
  305. (tokensSpec)?
  306. ( a:ACTION {behavior.refMemberAction(a);} )?
  307. ;
  308. rules
  309.     :   (
  310. options {
  311. // limitation of appox LL(k) says ambig upon
  312. // DOC_COMMENT TOKEN_REF, but that's an impossible sequence
  313. warnWhenFollowAmbig=false;
  314. }
  315. : rule
  316. )+
  317.     ;
  318. rule
  319. {
  320. String access="public"; 
  321. Token idTok;
  322. String doc=null;
  323. boolean ruleAutoGen = true;
  324. blockNesting = -1; // block increments, so -1 to make rule at level 0
  325. }
  326. :
  327. ( d:DOC_COMMENT {doc=d.getText();}
  328. )?
  329. ( p1:"protected" {access=p1.getText();}
  330. | p2:"public" {access=p2.getText();}
  331. | p3:"private" {access=p3.getText();}
  332. )?
  333. idTok = id
  334. ( BANG { ruleAutoGen = false; } )?
  335. {
  336. behavior.defineRuleName(idTok, access, ruleAutoGen, doc);
  337. }
  338. ( aa:ARG_ACTION { behavior.refArgAction(aa); }  )?
  339. ( "returns" rt:ARG_ACTION { behavior.refReturnAction(rt); } )?
  340. ( ruleOptionsSpec )?
  341. (a:ACTION {behavior.refInitAction(a);})?
  342. COLON block SEMI
  343. ( exceptionGroup )?
  344. {behavior.endRule(idTok.getText());}
  345. ;
  346. /*
  347. //
  348. // for now, syntax error in rule aborts the whole grammar
  349. //
  350. exception catch [ParserException ex] {
  351. behavior.abortRule(idTok);
  352. behavior.hasError();
  353. // Consume until something that looks like end of a rule
  354. consume();
  355. while (LA(1) != SEMI && LA(1) != EOF) {
  356. consume();
  357. }
  358. consume();
  359. }
  360. */
  361. ruleOptionsSpec 
  362. { Token idTok; Token value; }
  363. : OPTIONS
  364. (
  365. idTok = id
  366. ASSIGN
  367. value = optionValue
  368. { behavior.setRuleOption(idTok, value); }
  369. SEMI
  370. )*
  371. RCURLY
  372. ;
  373. block
  374.     :   {blockNesting++;}
  375. alternative ( OR alternative )*
  376. {blockNesting--;}
  377.     ;
  378. alternative
  379. { boolean altAutoGen = true; }
  380.     :
  381. (BANG { altAutoGen=false;} )?
  382. {behavior.beginAlt(altAutoGen);} 
  383. ( element )* ( exceptionSpecNoLabel )?
  384. {behavior.endAlt();}
  385.     ;
  386. exceptionGroup
  387. : { behavior.beginExceptionGroup(); }
  388. ( exceptionSpec )+
  389. { behavior.endExceptionGroup(); }
  390.    ;
  391. exceptionSpec 
  392. { Token labelAction = null; }
  393.    :
  394.    "exception"
  395.    ( aa:ARG_ACTION { labelAction = aa; } )?
  396.    { behavior.beginExceptionSpec(labelAction); }
  397.    ( exceptionHandler )*
  398.    { behavior.endExceptionSpec(); }
  399.    ;
  400. exceptionSpecNoLabel
  401.    :
  402.    "exception"
  403.    { behavior.beginExceptionSpec(null); }
  404.    ( exceptionHandler )*
  405.    { behavior.endExceptionSpec(); }
  406.    ;
  407. exceptionHandler
  408. { Token exType; Token exName; }
  409.    :
  410.    "catch"
  411.    a1:ARG_ACTION
  412.    a2:ACTION
  413.    { behavior.refExceptionHandler(a1, a2.getText()); }
  414.    ;
  415. element
  416. : elementNoOptionSpec (elementOptionSpec)?
  417. ;
  418. elementOptionSpec
  419. {
  420. Token o=null, v=null;
  421. }
  422. : OPEN_ELEMENT_OPTION
  423. o=id ASSIGN v=optionValue
  424. {behavior.refElementOption(o,v);}
  425. (
  426. SEMI
  427. o=id ASSIGN v=optionValue
  428. {behavior.refElementOption(o,v);}
  429. )*
  430. CLOSE_ELEMENT_OPTION
  431. ;
  432. elementNoOptionSpec
  433. Token label = null; 
  434. Token assignId = null; 
  435. Token args = null; 
  436. int autoGen = GrammarElement.AUTO_GEN_NONE;
  437. }
  438. : assignId=id 
  439. ASSIGN
  440. (label=id COLON)?
  441. ( rr:RULE_REF
  442. ( aa:ARG_ACTION { args=aa; } )?
  443. ( BANG { autoGen = GrammarElement.AUTO_GEN_BANG; } )?
  444. { behavior.refRule(assignId, rr, label, args, autoGen); } 
  445. | // this syntax only valid for lexer
  446. tr:TOKEN_REF
  447. ( aa2:ARG_ACTION { args=aa2; } )?
  448. { behavior.refToken(assignId, tr, label, args, false, autoGen, lastInRule()); } 
  449. )
  450. |
  451. (label=id COLON)? 
  452. ( r2:RULE_REF
  453. ( aa3:ARG_ACTION { args=aa3; } )?
  454. ( BANG { autoGen = GrammarElement.AUTO_GEN_BANG; } )?
  455. { behavior.refRule(assignId, r2, label, args, autoGen); } 
  456. |
  457. range [label]
  458. |
  459. terminal [label] 
  460. |
  461. NOT_OP 
  462. ( notTerminal[label]
  463. | ebnf[label,true]
  464. )
  465. |
  466. ebnf[label,false]
  467. )
  468. |
  469. a:ACTION { behavior.refAction(a);}
  470. |
  471. p:SEMPRED { behavior.refSemPred(p);}
  472. |
  473. tree
  474. ;
  475. tree :
  476. lp:TREE_BEGIN
  477. { behavior.beginTree(lp.getLine()); }
  478. rootNode
  479. {behavior.beginChildList();}
  480. ( element )+
  481. {behavior.endChildList();}
  482. RPAREN
  483. { behavior.endTree(); }
  484. ;
  485. rootNode
  486. { Token label = null; }
  487. :
  488. (label=id COLON)? 
  489. terminal[label]
  490. // | range[null]
  491. ;
  492. ebnf 
  493. [ Token label, boolean not ]
  494. : lp:LPAREN 
  495. {behavior.beginSubRule(label, lp.getLine(), not);}
  496. (
  497. // 2nd alt and optional branch ambig due to
  498. // linear approx LL(2) issue.  COLON ACTION
  499. // matched correctly in 2nd alt.
  500. options {
  501. warnWhenFollowAmbig = false;
  502. }
  503. :
  504. subruleOptionsSpec
  505. ( aa:ACTION {behavior.refInitAction(aa);} )?
  506. COLON
  507. | ab:ACTION {behavior.refInitAction(ab);}
  508. COLON
  509. )?
  510. block 
  511. RPAREN
  512. ( ( QUESTION{behavior.optionalSubRule();}
  513. | STAR {behavior.zeroOrMoreSubRule();;}
  514. | PLUS {behavior.oneOrMoreSubRule();}
  515. )?
  516. ( BANG {behavior.noASTSubRule(); } )?
  517. |
  518. IMPLIES {behavior.synPred();}
  519. )
  520. {behavior.endSubRule();}
  521. ;
  522. ast_type_spec
  523. returns [ int autoGen ]
  524. { autoGen = GrammarElement.AUTO_GEN_NONE; }
  525. : ( CARET { autoGen = GrammarElement.AUTO_GEN_CARET; }
  526. | BANG { autoGen = GrammarElement.AUTO_GEN_BANG; }
  527. )?
  528. ;
  529. range
  530. [ Token label ]
  531. {
  532. Token trLeft=null;
  533. Token trRight=null;
  534. int autoGen=GrammarElement.AUTO_GEN_NONE;
  535. }
  536. : crLeft:CHAR_LITERAL RANGE crRight:CHAR_LITERAL
  537. ( BANG { autoGen = GrammarElement.AUTO_GEN_BANG; } )?
  538. { behavior.refCharRange(crLeft, crRight, label, autoGen, lastInRule()); }
  539. |
  540. (t:TOKEN_REF{trLeft=t;}|u:STRING_LITERAL{trLeft=u;}) 
  541. RANGE
  542. (v:TOKEN_REF{trRight=v;}|w:STRING_LITERAL{trRight=w;}) 
  543. autoGen = ast_type_spec
  544. { behavior.refTokenRange(trLeft, trRight, label, autoGen, lastInRule()); }
  545. ;
  546. terminal
  547. [ Token label ]
  548. int autoGen=GrammarElement.AUTO_GEN_NONE;
  549. Token args=null;
  550. }
  551. :
  552. cl:CHAR_LITERAL
  553. ( BANG { autoGen = GrammarElement.AUTO_GEN_BANG; } )?
  554. {behavior.refCharLiteral(cl, label, false, autoGen, lastInRule());}
  555. |
  556. tr:TOKEN_REF
  557. autoGen = ast_type_spec
  558. // Args are only valid for lexer
  559. ( aa:ARG_ACTION { args=aa; } )?
  560. { behavior.refToken(null, tr, label, args, false, autoGen, lastInRule()); } 
  561. |
  562. sl:STRING_LITERAL
  563. autoGen = ast_type_spec
  564. {behavior.refStringLiteral(sl, label, autoGen, lastInRule());}
  565. |
  566. wi:WILDCARD
  567. autoGen = ast_type_spec
  568. {behavior.refWildcard(wi, label, autoGen);}
  569. ;
  570. notTerminal
  571. [ Token label ]
  572. { int autoGen=GrammarElement.AUTO_GEN_NONE; }
  573. :
  574. cl:CHAR_LITERAL
  575. ( BANG { autoGen = GrammarElement.AUTO_GEN_BANG; } )?
  576. {behavior.refCharLiteral(cl, label, true, autoGen, lastInRule());}
  577. |
  578. tr:TOKEN_REF
  579. autoGen = ast_type_spec
  580. {behavior.refToken(null, tr, label, null, true, autoGen, lastInRule());}
  581. ;
  582. /** Match a.b.c.d qualified ids; WILDCARD here is overloaded as
  583.  *  id separator; that is, I need a reference to the '.' token.
  584.  */
  585. qualifiedID returns [Token qidTok=null]
  586. {
  587. StringBuffer buf = new StringBuffer(30);
  588. Token a;
  589. }
  590. : a=id {buf.append(a.getText());}
  591. ( WILDCARD a=id
  592. {buf.append('.'); buf.append(a.getText());}
  593. )*
  594. {
  595.  // can use either TOKEN_REF or RULE_REF; should
  596.  // really create a QID or something instead.
  597.  qidTok = new CommonToken(TOKEN_REF, buf.toString());
  598.  qidTok.setLine(a.getLine());
  599. }
  600. ;
  601. id
  602. returns [ Token idTok ]
  603. { idTok = null; }
  604. : a:TOKEN_REF {idTok = a;}
  605. | b:RULE_REF {idTok = b;}
  606. ;
  607. class ANTLRLexer extends Lexer;
  608. options {
  609. k=2;
  610. exportVocab=ANTLR;
  611. testLiterals=false;
  612. interactive=true;
  613. }
  614. tokens {
  615. "options";
  616. }
  617. {
  618. /**Convert 'c' to an integer char value. */
  619. public static int escapeCharValue(String cs) {
  620. //System.out.println("escapeCharValue("+cs+")");
  621. if ( cs.charAt(1)!='\' ) return 0;
  622. switch ( cs.charAt(2) ) {
  623. case 'b' : return 'b';
  624. case 'r' : return 'r';
  625. case 't' : return 't';
  626. case 'n' : return 'n';
  627. case 'f' : return 'f';
  628. case '"' : return '"';
  629. case ''' :return ''';
  630. case '\' :return '\';
  631. case 'u' :
  632. // Unicode char
  633. if (cs.length() != 8) {
  634. return 0;
  635. }
  636. else {
  637. return
  638. Character.digit(cs.charAt(3), 16) * 16 * 16 * 16 +
  639. Character.digit(cs.charAt(4), 16) * 16 * 16 +
  640. Character.digit(cs.charAt(5), 16) * 16 +
  641. Character.digit(cs.charAt(6), 16);
  642. }
  643. case '0' :
  644. case '1' :
  645. case '2' :
  646. case '3' :
  647. if ( cs.length()>5 && Character.isDigit(cs.charAt(4)) ) {
  648. return (cs.charAt(2)-'0')*8*8 + (cs.charAt(3)-'0')*8 + (cs.charAt(4)-'0');
  649. }
  650. if ( cs.length()>4 && Character.isDigit(cs.charAt(3)) ) {
  651. return (cs.charAt(2)-'0')*8 + (cs.charAt(3)-'0');
  652. }
  653. return cs.charAt(2)-'0';
  654. case '4' :
  655. case '5' :
  656. case '6' :
  657. case '7' :
  658. if ( cs.length()>4 && Character.isDigit(cs.charAt(3)) ) {
  659. return (cs.charAt(2)-'0')*8 + (cs.charAt(3)-'0');
  660. }
  661. return cs.charAt(2)-'0';
  662. default :
  663. return 0;
  664. }
  665. }
  666. public static int tokenTypeForCharLiteral(String lit) {
  667. if ( lit.length()>3 ) {  // does char contain escape?
  668. return escapeCharValue(lit);
  669. }
  670. else {
  671. return lit.charAt(1);
  672. }
  673. }
  674. }
  675. WS : ( /* 'r' 'n' can be matched in one alternative or by matching
  676. 'r' in one iteration and 'n' in another.  I am trying to
  677. handle any flavor of newline that comes in, but the language
  678. that allows both "rn" and "r" and "n" to all be valid
  679. newline is ambiguous.  Consequently, the resulting grammar
  680. must be ambiguous.  I'm shutting this warning off.
  681.  */
  682. options {
  683. generateAmbigWarnings=false;
  684. }
  685. : ' '
  686. | 't'
  687. | 'r' 'n' {newline();}
  688. | 'r' {newline();}
  689. | 'n' {newline();}
  690. )
  691. { $setType(Token.SKIP); }
  692. ;
  693. COMMENT : 
  694. ( SL_COMMENT | t:ML_COMMENT {$setType(t.getType());} )
  695. {if ( _ttype != DOC_COMMENT ) $setType(Token.SKIP);}
  696. ;
  697. protected
  698. SL_COMMENT :
  699. "//"
  700. ( ~('n'|'r') )*
  701. (
  702. /* 'r' 'n' can be matched in one alternative or by matching
  703. 'r' and then in the next token.  The language
  704. that allows both "rn" and "r" and "n" to all be valid
  705. newline is ambiguous.  Consequently, the resulting grammar
  706. must be ambiguous.  I'm shutting this warning off.
  707.  */
  708. options {
  709. generateAmbigWarnings=false;
  710. }
  711. : 'r' 'n'
  712. | 'r'
  713. | 'n'
  714. )
  715. { newline(); }
  716. ;
  717. protected
  718. ML_COMMENT :
  719. "/*"
  720. ( { LA(2)!='/' }? '*' {$setType(DOC_COMMENT);}
  721. |
  722. )
  723. (
  724. /* 'r' 'n' can be matched in one alternative or by matching
  725. 'r' and then in the next token.  The language
  726. that allows both "rn" and "r" and "n" to all be valid
  727. newline is ambiguous.  Consequently, the resulting grammar
  728. must be ambiguous.  I'm shutting this warning off.
  729.  */
  730. options {
  731. greedy=false;  // make it exit upon "*/"
  732. generateAmbigWarnings=false; // shut off newline errors
  733. }
  734. : 'r' 'n' {newline();}
  735. | 'r' {newline();}
  736. | 'n' {newline();}
  737. | ~('n'|'r')
  738. )*
  739. "*/"
  740. ;
  741. OPEN_ELEMENT_OPTION
  742. : '<'
  743. ;
  744. CLOSE_ELEMENT_OPTION
  745. : '>'
  746. ;
  747. COMMA : ',';
  748. QUESTION : '?' ;
  749. TREE_BEGIN : "#(" ;
  750. LPAREN: '(' ;
  751. RPAREN: ')' ;
  752. COLON : ':' ;
  753. STAR: '*' ;
  754. PLUS: '+' ;
  755. ASSIGN : '=' ;
  756. IMPLIES : "=>" ;
  757. SEMI: ';' ;
  758. CARET : '^' ;
  759. BANG : '!' ;
  760. OR : '|' ;
  761. WILDCARD : '.' ;
  762. RANGE : ".." ;
  763. NOT_OP : '~' ;
  764. RCURLY: '}' ;
  765. CHAR_LITERAL
  766. : ''' (ESC|~''') '''
  767. ;
  768. STRING_LITERAL
  769. : '"' (ESC|~'"')* '"'
  770. ;
  771. protected
  772. ESC : '\'
  773. ( 'n'
  774. | 'r'
  775. | 't'
  776. | 'b'
  777. | 'f'
  778. | 'w'
  779. | 'a'
  780. | '"'
  781. | '''
  782. | '\'
  783. | ('0'..'3')
  784. (
  785. options {
  786. warnWhenFollowAmbig = false;
  787. }
  788. :
  789. ('0'..'9')
  790. (
  791. options {
  792. warnWhenFollowAmbig = false;
  793. }
  794. :
  795. '0'..'9'
  796. )?
  797. )?
  798. | ('4'..'7')
  799. (
  800. options {
  801. warnWhenFollowAmbig = false;
  802. }
  803. :
  804. ('0'..'9')
  805. )?
  806. | 'u' XDIGIT XDIGIT XDIGIT XDIGIT
  807. )
  808. ;
  809. protected
  810. DIGIT
  811. : '0'..'9'
  812. ;
  813. protected
  814. XDIGIT :
  815. '0' .. '9'
  816. | 'a' .. 'f'
  817. | 'A' .. 'F'
  818. ;
  819. protected
  820. VOCAB
  821. : '3'..'176' // common ASCII
  822. ;
  823. INT : ('0'..'9')+
  824. ;
  825. ARG_ACTION 
  826.    :
  827. NESTED_ARG_ACTION
  828. { setText(Tool.stripFrontBack(getText(), "[", "]")); }
  829. ;
  830. protected
  831. NESTED_ARG_ACTION :
  832. '['
  833. (
  834. /* 'r' 'n' can be matched in one alternative or by matching
  835. 'r' and then 'n' in the next iteration.
  836.  */
  837. options {
  838. generateAmbigWarnings=false; // shut off newline errors
  839. }
  840. : NESTED_ARG_ACTION
  841. | 'r' 'n' {newline();}
  842. | 'r' {newline();}
  843. | 'n' {newline();}
  844. | CHAR_LITERAL 
  845. | STRING_LITERAL 
  846. | ~']'
  847. )* 
  848. ']'
  849. ;
  850. ACTION 
  851. {int actionLine=getLine();}
  852. : NESTED_ACTION
  853. ( '?' {_ttype = SEMPRED;} )?
  854. {
  855. if ( _ttype==ACTION ) {
  856. setText(Tool.stripFrontBack(getText(), "{", "}"));
  857. }
  858. else {
  859. setText(Tool.stripFrontBack(getText(), "{", "}?"));
  860. }
  861. CommonToken t = new CommonToken(_ttype,$getText);
  862. t.setLine(actionLine); // set action line to start
  863. $setToken(t);
  864. }
  865. ;
  866. protected
  867. NESTED_ACTION : 
  868. '{'
  869. (
  870. options {
  871. greedy = false; // exit upon '}'
  872. }
  873. :
  874. (
  875. options {
  876. generateAmbigWarnings = false; // shut off newline warning
  877. }
  878. : 'r' 'n' {newline();}
  879. | 'r'  {newline();}
  880. | 'n' {newline();}
  881. )
  882. | NESTED_ACTION
  883. | CHAR_LITERAL
  884. | COMMENT
  885. | STRING_LITERAL
  886. | .
  887. )*
  888. '}'
  889.    ;
  890. TOKEN_REF
  891. options { testLiterals = true; }
  892. : 'A'..'Z'
  893. ( // scarf as many letters/numbers as you can
  894. options {
  895. warnWhenFollowAmbig=false;
  896. }
  897. :
  898. 'a'..'z'|'A'..'Z'|'_'|'0'..'9'
  899. )*
  900. ;
  901. // we get a warning here when looking for options '{', but it works right
  902. RULE_REF
  903. {
  904. int t=0;
  905. }
  906. : t=INTERNAL_RULE_REF {_ttype=t;}
  907. ( {t==LITERAL_options}? WS_LOOP ('{' {_ttype = OPTIONS;})?
  908. | {t==LITERAL_tokens}? WS_LOOP ('{' {_ttype = TOKENS;})?
  909. |
  910. )
  911. ;
  912. protected
  913. WS_LOOP
  914. : ( // grab as much WS as you can
  915. options {
  916. warnWhenFollowAmbig=false;
  917. }
  918. :
  919. WS
  920. )*
  921. ;
  922. protected
  923. INTERNAL_RULE_REF returns [int t]
  924. {
  925. t = RULE_REF;
  926. }
  927. : 'a'..'z'
  928. ( // scarf as many letters/numbers as you can
  929. options {
  930. warnWhenFollowAmbig=false;
  931. }
  932. :
  933. 'a'..'z'|'A'..'Z'|'_'|'0'..'9'
  934. )*
  935. {t = testLiteralsTable(t);}
  936. ;
  937. protected 
  938. WS_OPT :
  939. (WS)?
  940. ;
  941. // remove after the class variants of the scanners/parsers go
  942. // away. this rule, just forces the lexer to use the most
  943. // complicated class so I can get rid of the others.
  944. protected
  945. NOT_USEFUL
  946. : ('a')=>'a'
  947. | 'a'
  948. ;