PageRenderTime 56ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 1ms

/Dependencies/boo/lib/antlr-2.7.5/antlr/JavaCodeGenerator.java

https://github.com/w4x/boolangstudio
Java | 3484 lines | 2405 code | 361 blank | 718 comment | 691 complexity | d399396ee38472edf7c786462382b1ca MD5 | raw file
Possible License(s): GPL-2.0

Large files files are truncated, but you can click here to view the full file

  1. package antlr;
  2. /* ANTLR Translator Generator
  3. * Project led by Terence Parr at http://www.jGuru.com
  4. * Software rights: http://www.antlr.org/license.html
  5. *
  6. * $Id: //depot/code/org.antlr/release/antlr-2.7.5/antlr/JavaCodeGenerator.java#1 $
  7. */
  8. import java.util.Enumeration;
  9. import java.util.Hashtable;
  10. import antlr.collections.impl.BitSet;
  11. import antlr.collections.impl.Vector;
  12. import java.io.PrintWriter; //SAS: changed for proper text file io
  13. import java.io.IOException;
  14. import java.io.FileWriter;
  15. /**Generate MyParser.java, MyLexer.java and MyParserTokenTypes.java */
  16. public class JavaCodeGenerator extends CodeGenerator {
  17. // non-zero if inside syntactic predicate generation
  18. protected int syntacticPredLevel = 0;
  19. // Are we generating ASTs (for parsers and tree parsers) right now?
  20. protected boolean genAST = false;
  21. // Are we saving the text consumed (for lexers) right now?
  22. protected boolean saveText = false;
  23. // Grammar parameters set up to handle different grammar classes.
  24. // These are used to get instanceof tests out of code generation
  25. String labeledElementType;
  26. String labeledElementASTType;
  27. String labeledElementInit;
  28. String commonExtraArgs;
  29. String commonExtraParams;
  30. String commonLocalVars;
  31. String lt1Value;
  32. String exceptionThrown;
  33. String throwNoViable;
  34. /** Tracks the rule being generated. Used for mapTreeId */
  35. RuleBlock currentRule;
  36. /** Tracks the rule or labeled subrule being generated. Used for
  37. AST generation. */
  38. String currentASTResult;
  39. /** Mapping between the ids used in the current alt, and the
  40. * names of variables used to represent their AST values.
  41. */
  42. Hashtable treeVariableMap = new Hashtable();
  43. /** Used to keep track of which AST variables have been defined in a rule
  44. * (except for the #rule_name and #rule_name_in var's
  45. */
  46. Hashtable declaredASTVariables = new Hashtable();
  47. /* Count of unnamed generated variables */
  48. int astVarNumber = 1;
  49. /** Special value used to mark duplicate in treeVariableMap */
  50. protected static final String NONUNIQUE = new String();
  51. public static final int caseSizeThreshold = 127; // ascii is max
  52. private Vector semPreds;
  53. /** Create a Java code-generator using the given Grammar.
  54. * The caller must still call setTool, setBehavior, and setAnalyzer
  55. * before generating code.
  56. */
  57. public JavaCodeGenerator() {
  58. super();
  59. charFormatter = new JavaCharFormatter();
  60. }
  61. /** Adds a semantic predicate string to the sem pred vector
  62. These strings will be used to build an array of sem pred names
  63. when building a debugging parser. This method should only be
  64. called when the debug option is specified
  65. */
  66. protected int addSemPred(String predicate) {
  67. semPreds.appendElement(predicate);
  68. return semPreds.size() - 1;
  69. }
  70. public void exitIfError() {
  71. if (antlrTool.hasError()) {
  72. antlrTool.fatalError("Exiting due to errors.");
  73. }
  74. }
  75. /**Generate the parser, lexer, treeparser, and token types in Java */
  76. public void gen() {
  77. // Do the code generation
  78. try {
  79. // Loop over all grammars
  80. Enumeration grammarIter = behavior.grammars.elements();
  81. while (grammarIter.hasMoreElements()) {
  82. Grammar g = (Grammar)grammarIter.nextElement();
  83. // Connect all the components to each other
  84. g.setGrammarAnalyzer(analyzer);
  85. g.setCodeGenerator(this);
  86. analyzer.setGrammar(g);
  87. // To get right overloading behavior across hetrogeneous grammars
  88. setupGrammarParameters(g);
  89. g.generate();
  90. // print out the grammar with lookahead sets (and FOLLOWs)
  91. // System.out.print(g.toString());
  92. exitIfError();
  93. }
  94. // Loop over all token managers (some of which are lexers)
  95. Enumeration tmIter = behavior.tokenManagers.elements();
  96. while (tmIter.hasMoreElements()) {
  97. TokenManager tm = (TokenManager)tmIter.nextElement();
  98. if (!tm.isReadOnly()) {
  99. // Write the token manager tokens as Java
  100. // this must appear before genTokenInterchange so that
  101. // labels are set on string literals
  102. genTokenTypes(tm);
  103. // Write the token manager tokens as plain text
  104. genTokenInterchange(tm);
  105. }
  106. exitIfError();
  107. }
  108. }
  109. catch (IOException e) {
  110. antlrTool.reportException(e, null);
  111. }
  112. }
  113. /** Generate code for the given grammar element.
  114. * @param blk The {...} action to generate
  115. */
  116. public void gen(ActionElement action) {
  117. if (DEBUG_CODE_GENERATOR) System.out.println("genAction(" + action + ")");
  118. if (action.isSemPred) {
  119. genSemPred(action.actionText, action.line);
  120. }
  121. else {
  122. if (grammar.hasSyntacticPredicate) {
  123. println("if ( inputState.guessing==0 ) {");
  124. tabs++;
  125. }
  126. // get the name of the followSet for the current rule so that we
  127. // can replace $FOLLOW in the .g file.
  128. ActionTransInfo tInfo = new ActionTransInfo();
  129. String actionStr = processActionForSpecialSymbols(action.actionText,
  130. action.getLine(),
  131. currentRule,
  132. tInfo);
  133. if (tInfo.refRuleRoot != null) {
  134. // Somebody referenced "#rule", make sure translated var is valid
  135. // assignment to #rule is left as a ref also, meaning that assignments
  136. // with no other refs like "#rule = foo();" still forces this code to be
  137. // generated (unnecessarily).
  138. println(tInfo.refRuleRoot + " = (" + labeledElementASTType + ")currentAST.root;");
  139. }
  140. // dump the translated action
  141. printAction(actionStr);
  142. if (tInfo.assignToRoot) {
  143. // Somebody did a "#rule=", reset internal currentAST.root
  144. println("currentAST.root = " + tInfo.refRuleRoot + ";");
  145. // reset the child pointer too to be last sibling in sibling list
  146. println("currentAST.child = " + tInfo.refRuleRoot + "!=null &&" + tInfo.refRuleRoot + ".getFirstChild()!=null ?");
  147. tabs++;
  148. println(tInfo.refRuleRoot + ".getFirstChild() : " + tInfo.refRuleRoot + ";");
  149. tabs--;
  150. println("currentAST.advanceChildToEnd();");
  151. }
  152. if (grammar.hasSyntacticPredicate) {
  153. tabs--;
  154. println("}");
  155. }
  156. }
  157. }
  158. /** Generate code for the given grammar element.
  159. * @param blk The "x|y|z|..." block to generate
  160. */
  161. public void gen(AlternativeBlock blk) {
  162. if (DEBUG_CODE_GENERATOR) System.out.println("gen(" + blk + ")");
  163. println("{");
  164. genBlockPreamble(blk);
  165. genBlockInitAction(blk);
  166. // Tell AST generation to build subrule result
  167. String saveCurrentASTResult = currentASTResult;
  168. if (blk.getLabel() != null) {
  169. currentASTResult = blk.getLabel();
  170. }
  171. boolean ok = grammar.theLLkAnalyzer.deterministic(blk);
  172. JavaBlockFinishingInfo howToFinish = genCommonBlock(blk, true);
  173. genBlockFinish(howToFinish, throwNoViable);
  174. println("}");
  175. // Restore previous AST generation
  176. currentASTResult = saveCurrentASTResult;
  177. }
  178. /** Generate code for the given grammar element.
  179. * @param blk The block-end element to generate. Block-end
  180. * elements are synthesized by the grammar parser to represent
  181. * the end of a block.
  182. */
  183. public void gen(BlockEndElement end) {
  184. if (DEBUG_CODE_GENERATOR) System.out.println("genRuleEnd(" + end + ")");
  185. }
  186. /** Generate code for the given grammar element.
  187. * @param blk The character literal reference to generate
  188. */
  189. public void gen(CharLiteralElement atom) {
  190. if (DEBUG_CODE_GENERATOR) System.out.println("genChar(" + atom + ")");
  191. if (atom.getLabel() != null) {
  192. println(atom.getLabel() + " = " + lt1Value + ";");
  193. }
  194. boolean oldsaveText = saveText;
  195. saveText = saveText && atom.getAutoGenType() == GrammarElement.AUTO_GEN_NONE;
  196. genMatch(atom);
  197. saveText = oldsaveText;
  198. }
  199. /** Generate code for the given grammar element.
  200. * @param blk The character-range reference to generate
  201. */
  202. public void gen(CharRangeElement r) {
  203. if (r.getLabel() != null && syntacticPredLevel == 0) {
  204. println(r.getLabel() + " = " + lt1Value + ";");
  205. }
  206. boolean flag = ( grammar instanceof LexerGrammar &&
  207. ( !saveText ||
  208. r.getAutoGenType() ==
  209. GrammarElement.AUTO_GEN_BANG ) );
  210. if (flag) {
  211. println("_saveIndex=text.length();");
  212. }
  213. println("matchRange(" + r.beginText + "," + r.endText + ");");
  214. if (flag) {
  215. println("text.setLength(_saveIndex);");
  216. }
  217. }
  218. /** Generate the lexer Java file */
  219. public void gen(LexerGrammar g) throws IOException {
  220. // If debugging, create a new sempred vector for this grammar
  221. if (g.debuggingOutput)
  222. semPreds = new Vector();
  223. setGrammar(g);
  224. if (!(grammar instanceof LexerGrammar)) {
  225. antlrTool.panic("Internal error generating lexer");
  226. }
  227. // SAS: moved output creation to method so a subclass can change
  228. // how the output is generated (for VAJ interface)
  229. setupOutput(grammar.getClassName());
  230. genAST = false; // no way to gen trees.
  231. saveText = true; // save consumed characters.
  232. tabs = 0;
  233. // Generate header common to all Java output files
  234. genHeader();
  235. // Do not use printAction because we assume tabs==0
  236. println(behavior.getHeaderAction(""));
  237. // Generate header specific to lexer Java file
  238. // println("import java.io.FileInputStream;");
  239. println("import java.io.InputStream;");
  240. println("import antlr.TokenStreamException;");
  241. println("import antlr.TokenStreamIOException;");
  242. println("import antlr.TokenStreamRecognitionException;");
  243. println("import antlr.CharStreamException;");
  244. println("import antlr.CharStreamIOException;");
  245. println("import antlr.ANTLRException;");
  246. println("import java.io.Reader;");
  247. println("import java.util.Hashtable;");
  248. println("import antlr." + grammar.getSuperClass() + ";");
  249. println("import antlr.InputBuffer;");
  250. println("import antlr.ByteBuffer;");
  251. println("import antlr.CharBuffer;");
  252. println("import antlr.Token;");
  253. println("import antlr.CommonToken;");
  254. println("import antlr.RecognitionException;");
  255. println("import antlr.NoViableAltForCharException;");
  256. println("import antlr.MismatchedCharException;");
  257. println("import antlr.TokenStream;");
  258. println("import antlr.ANTLRHashString;");
  259. println("import antlr.LexerSharedInputState;");
  260. println("import antlr.collections.impl.BitSet;");
  261. println("import antlr.SemanticException;");
  262. // Generate user-defined lexer file preamble
  263. println(grammar.preambleAction.getText());
  264. // Generate lexer class definition
  265. String sup = null;
  266. if (grammar.superClass != null) {
  267. sup = grammar.superClass;
  268. }
  269. else {
  270. sup = "antlr." + grammar.getSuperClass();
  271. }
  272. // print javadoc comment if any
  273. if (grammar.comment != null) {
  274. _println(grammar.comment);
  275. }
  276. // get prefix (replaces "public" and lets user specify)
  277. String prefix = "public";
  278. Token tprefix = (Token)grammar.options.get("classHeaderPrefix");
  279. if (tprefix != null) {
  280. String p = StringUtils.stripFrontBack(tprefix.getText(), "\"", "\"");
  281. if (p != null) {
  282. prefix = p;
  283. }
  284. }
  285. print(prefix+" ");
  286. print("class " + grammar.getClassName() + " extends " + sup);
  287. println(" implements " + grammar.tokenManager.getName() + TokenTypesFileSuffix + ", TokenStream");
  288. Token tsuffix = (Token)grammar.options.get("classHeaderSuffix");
  289. if (tsuffix != null) {
  290. String suffix = StringUtils.stripFrontBack(tsuffix.getText(), "\"", "\"");
  291. if (suffix != null) {
  292. print(", " + suffix); // must be an interface name for Java
  293. }
  294. }
  295. println(" {");
  296. // Generate user-defined lexer class members
  297. print(
  298. processActionForSpecialSymbols(grammar.classMemberAction.getText(), grammar.classMemberAction.getLine(), currentRule, null)
  299. );
  300. //
  301. // Generate the constructor from InputStream, which in turn
  302. // calls the ByteBuffer constructor
  303. //
  304. println("public " + grammar.getClassName() + "(InputStream in) {");
  305. tabs++;
  306. println("this(new ByteBuffer(in));");
  307. tabs--;
  308. println("}");
  309. //
  310. // Generate the constructor from Reader, which in turn
  311. // calls the CharBuffer constructor
  312. //
  313. println("public " + grammar.getClassName() + "(Reader in) {");
  314. tabs++;
  315. println("this(new CharBuffer(in));");
  316. tabs--;
  317. println("}");
  318. println("public " + grammar.getClassName() + "(InputBuffer ib) {");
  319. tabs++;
  320. // if debugging, wrap the input buffer in a debugger
  321. if (grammar.debuggingOutput)
  322. println("this(new LexerSharedInputState(new antlr.debug.DebuggingInputBuffer(ib)));");
  323. else
  324. println("this(new LexerSharedInputState(ib));");
  325. tabs--;
  326. println("}");
  327. //
  328. // Generate the constructor from InputBuffer (char or byte)
  329. //
  330. println("public " + grammar.getClassName() + "(LexerSharedInputState state) {");
  331. tabs++;
  332. println("super(state);");
  333. // if debugging, set up array variables and call user-overridable
  334. // debugging setup method
  335. if (grammar.debuggingOutput) {
  336. println(" ruleNames = _ruleNames;");
  337. println(" semPredNames = _semPredNames;");
  338. println(" setupDebugging();");
  339. }
  340. // Generate the setting of various generated options.
  341. // These need to be before the literals since ANTLRHashString depends on
  342. // the casesensitive stuff.
  343. println("caseSensitiveLiterals = " + g.caseSensitiveLiterals + ";");
  344. println("setCaseSensitive(" + g.caseSensitive + ");");
  345. // Generate the initialization of a hashtable
  346. // containing the string literals used in the lexer
  347. // The literals variable itself is in CharScanner
  348. println("literals = new Hashtable();");
  349. Enumeration keys = grammar.tokenManager.getTokenSymbolKeys();
  350. while (keys.hasMoreElements()) {
  351. String key = (String)keys.nextElement();
  352. if (key.charAt(0) != '"') {
  353. continue;
  354. }
  355. TokenSymbol sym = grammar.tokenManager.getTokenSymbol(key);
  356. if (sym instanceof StringLiteralSymbol) {
  357. StringLiteralSymbol s = (StringLiteralSymbol)sym;
  358. println("literals.put(new ANTLRHashString(" + s.getId() + ", this), new Integer(" + s.getTokenType() + "));");
  359. }
  360. }
  361. tabs--;
  362. Enumeration ids;
  363. println("}");
  364. // generate the rule name array for debugging
  365. if (grammar.debuggingOutput) {
  366. println("private static final String _ruleNames[] = {");
  367. ids = grammar.rules.elements();
  368. int ruleNum = 0;
  369. while (ids.hasMoreElements()) {
  370. GrammarSymbol sym = (GrammarSymbol)ids.nextElement();
  371. if (sym instanceof RuleSymbol)
  372. println(" \"" + ((RuleSymbol)sym).getId() + "\",");
  373. }
  374. println("};");
  375. }
  376. // Generate nextToken() rule.
  377. // nextToken() is a synthetic lexer rule that is the implicit OR of all
  378. // user-defined lexer rules.
  379. genNextToken();
  380. // Generate code for each rule in the lexer
  381. ids = grammar.rules.elements();
  382. int ruleNum = 0;
  383. while (ids.hasMoreElements()) {
  384. RuleSymbol sym = (RuleSymbol)ids.nextElement();
  385. // Don't generate the synthetic rules
  386. if (!sym.getId().equals("mnextToken")) {
  387. genRule(sym, false, ruleNum++);
  388. }
  389. exitIfError();
  390. }
  391. // Generate the semantic predicate map for debugging
  392. if (grammar.debuggingOutput)
  393. genSemPredMap();
  394. // Generate the bitsets used throughout the lexer
  395. genBitsets(bitsetsUsed, ((LexerGrammar)grammar).charVocabulary.size());
  396. println("");
  397. println("}");
  398. // Close the lexer output stream
  399. currentOutput.close();
  400. currentOutput = null;
  401. }
  402. /** Generate code for the given grammar element.
  403. * @param blk The (...)+ block to generate
  404. */
  405. public void gen(OneOrMoreBlock blk) {
  406. if (DEBUG_CODE_GENERATOR) System.out.println("gen+(" + blk + ")");
  407. String label;
  408. String cnt;
  409. println("{");
  410. genBlockPreamble(blk);
  411. if (blk.getLabel() != null) {
  412. cnt = "_cnt_" + blk.getLabel();
  413. }
  414. else {
  415. cnt = "_cnt" + blk.ID;
  416. }
  417. println("int " + cnt + "=0;");
  418. if (blk.getLabel() != null) {
  419. label = blk.getLabel();
  420. }
  421. else {
  422. label = "_loop" + blk.ID;
  423. }
  424. println(label + ":");
  425. println("do {");
  426. tabs++;
  427. // generate the init action for ()+ ()* inside the loop
  428. // this allows us to do usefull EOF checking...
  429. genBlockInitAction(blk);
  430. // Tell AST generation to build subrule result
  431. String saveCurrentASTResult = currentASTResult;
  432. if (blk.getLabel() != null) {
  433. currentASTResult = blk.getLabel();
  434. }
  435. boolean ok = grammar.theLLkAnalyzer.deterministic(blk);
  436. // generate exit test if greedy set to false
  437. // and an alt is ambiguous with exit branch
  438. // or when lookahead derived purely from end-of-file
  439. // Lookahead analysis stops when end-of-file is hit,
  440. // returning set {epsilon}. Since {epsilon} is not
  441. // ambig with any real tokens, no error is reported
  442. // by deterministic() routines and we have to check
  443. // for the case where the lookahead depth didn't get
  444. // set to NONDETERMINISTIC (this only happens when the
  445. // FOLLOW contains real atoms + epsilon).
  446. boolean generateNonGreedyExitPath = false;
  447. int nonGreedyExitDepth = grammar.maxk;
  448. if (!blk.greedy &&
  449. blk.exitLookaheadDepth <= grammar.maxk &&
  450. blk.exitCache[blk.exitLookaheadDepth].containsEpsilon()) {
  451. generateNonGreedyExitPath = true;
  452. nonGreedyExitDepth = blk.exitLookaheadDepth;
  453. }
  454. else if (!blk.greedy &&
  455. blk.exitLookaheadDepth == LLkGrammarAnalyzer.NONDETERMINISTIC) {
  456. generateNonGreedyExitPath = true;
  457. }
  458. // generate exit test if greedy set to false
  459. // and an alt is ambiguous with exit branch
  460. if (generateNonGreedyExitPath) {
  461. if (DEBUG_CODE_GENERATOR) {
  462. System.out.println("nongreedy (...)+ loop; exit depth is " +
  463. blk.exitLookaheadDepth);
  464. }
  465. String predictExit =
  466. getLookaheadTestExpression(blk.exitCache,
  467. nonGreedyExitDepth);
  468. println("// nongreedy exit test");
  469. println("if ( " + cnt + ">=1 && " + predictExit + ") break " + label + ";");
  470. }
  471. JavaBlockFinishingInfo howToFinish = genCommonBlock(blk, false);
  472. genBlockFinish(
  473. howToFinish,
  474. "if ( " + cnt + ">=1 ) { break " + label + "; } else {" + throwNoViable + "}"
  475. );
  476. println(cnt + "++;");
  477. tabs--;
  478. println("} while (true);");
  479. println("}");
  480. // Restore previous AST generation
  481. currentASTResult = saveCurrentASTResult;
  482. }
  483. /** Generate the parser Java file */
  484. public void gen(ParserGrammar g) throws IOException {
  485. // if debugging, set up a new vector to keep track of sempred
  486. // strings for this grammar
  487. if (g.debuggingOutput)
  488. semPreds = new Vector();
  489. setGrammar(g);
  490. if (!(grammar instanceof ParserGrammar)) {
  491. antlrTool.panic("Internal error generating parser");
  492. }
  493. // Open the output stream for the parser and set the currentOutput
  494. // SAS: moved file setup so subclass could do it (for VAJ interface)
  495. setupOutput(grammar.getClassName());
  496. genAST = grammar.buildAST;
  497. tabs = 0;
  498. // Generate the header common to all output files.
  499. genHeader();
  500. // Do not use printAction because we assume tabs==0
  501. println(behavior.getHeaderAction(""));
  502. // Generate header for the parser
  503. println("import antlr.TokenBuffer;");
  504. println("import antlr.TokenStreamException;");
  505. println("import antlr.TokenStreamIOException;");
  506. println("import antlr.ANTLRException;");
  507. println("import antlr." + grammar.getSuperClass() + ";");
  508. println("import antlr.Token;");
  509. println("import antlr.TokenStream;");
  510. println("import antlr.RecognitionException;");
  511. println("import antlr.NoViableAltException;");
  512. println("import antlr.MismatchedTokenException;");
  513. println("import antlr.SemanticException;");
  514. println("import antlr.ParserSharedInputState;");
  515. println("import antlr.collections.impl.BitSet;");
  516. if ( genAST ) {
  517. println("import antlr.collections.AST;");
  518. println("import java.util.Hashtable;");
  519. println("import antlr.ASTFactory;");
  520. println("import antlr.ASTPair;");
  521. println("import antlr.collections.impl.ASTArray;");
  522. }
  523. // Output the user-defined parser preamble
  524. println(grammar.preambleAction.getText());
  525. // Generate parser class definition
  526. String sup = null;
  527. if (grammar.superClass != null)
  528. sup = grammar.superClass;
  529. else
  530. sup = "antlr." + grammar.getSuperClass();
  531. // print javadoc comment if any
  532. if (grammar.comment != null) {
  533. _println(grammar.comment);
  534. }
  535. // get prefix (replaces "public" and lets user specify)
  536. String prefix = "public";
  537. Token tprefix = (Token)grammar.options.get("classHeaderPrefix");
  538. if (tprefix != null) {
  539. String p = StringUtils.stripFrontBack(tprefix.getText(), "\"", "\"");
  540. if (p != null) {
  541. prefix = p;
  542. }
  543. }
  544. print(prefix+" ");
  545. print("class " + grammar.getClassName() + " extends " + sup);
  546. println(" implements " + grammar.tokenManager.getName() + TokenTypesFileSuffix);
  547. Token tsuffix = (Token)grammar.options.get("classHeaderSuffix");
  548. if (tsuffix != null) {
  549. String suffix = StringUtils.stripFrontBack(tsuffix.getText(), "\"", "\"");
  550. if (suffix != null)
  551. print(", " + suffix); // must be an interface name for Java
  552. }
  553. println(" {");
  554. // set up an array of all the rule names so the debugger can
  555. // keep track of them only by number -- less to store in tree...
  556. if (grammar.debuggingOutput) {
  557. println("private static final String _ruleNames[] = {");
  558. Enumeration ids = grammar.rules.elements();
  559. int ruleNum = 0;
  560. while (ids.hasMoreElements()) {
  561. GrammarSymbol sym = (GrammarSymbol)ids.nextElement();
  562. if (sym instanceof RuleSymbol)
  563. println(" \"" + ((RuleSymbol)sym).getId() + "\",");
  564. }
  565. println("};");
  566. }
  567. // Generate user-defined parser class members
  568. print(
  569. processActionForSpecialSymbols(grammar.classMemberAction.getText(), grammar.classMemberAction.getLine(), currentRule, null)
  570. );
  571. // Generate parser class constructor from TokenBuffer
  572. println("");
  573. println("protected " + grammar.getClassName() + "(TokenBuffer tokenBuf, int k) {");
  574. println(" super(tokenBuf,k);");
  575. println(" tokenNames = _tokenNames;");
  576. // if debugging, set up arrays and call the user-overridable
  577. // debugging setup method
  578. if (grammar.debuggingOutput) {
  579. println(" ruleNames = _ruleNames;");
  580. println(" semPredNames = _semPredNames;");
  581. println(" setupDebugging(tokenBuf);");
  582. }
  583. if ( grammar.buildAST ) {
  584. println(" buildTokenTypeASTClassMap();");
  585. println(" astFactory = new ASTFactory(getTokenTypeToASTClassMap());");
  586. }
  587. println("}");
  588. println("");
  589. println("public " + grammar.getClassName() + "(TokenBuffer tokenBuf) {");
  590. println(" this(tokenBuf," + grammar.maxk + ");");
  591. println("}");
  592. println("");
  593. // Generate parser class constructor from TokenStream
  594. println("protected " + grammar.getClassName() + "(TokenStream lexer, int k) {");
  595. println(" super(lexer,k);");
  596. println(" tokenNames = _tokenNames;");
  597. // if debugging, set up arrays and call the user-overridable
  598. // debugging setup method
  599. if (grammar.debuggingOutput) {
  600. println(" ruleNames = _ruleNames;");
  601. println(" semPredNames = _semPredNames;");
  602. println(" setupDebugging(lexer);");
  603. }
  604. if ( grammar.buildAST ) {
  605. println(" buildTokenTypeASTClassMap();");
  606. println(" astFactory = new ASTFactory(getTokenTypeToASTClassMap());");
  607. }
  608. println("}");
  609. println("");
  610. println("public " + grammar.getClassName() + "(TokenStream lexer) {");
  611. println(" this(lexer," + grammar.maxk + ");");
  612. println("}");
  613. println("");
  614. println("public " + grammar.getClassName() + "(ParserSharedInputState state) {");
  615. println(" super(state," + grammar.maxk + ");");
  616. println(" tokenNames = _tokenNames;");
  617. if ( grammar.buildAST ) {
  618. println(" buildTokenTypeASTClassMap();");
  619. println(" astFactory = new ASTFactory(getTokenTypeToASTClassMap());");
  620. }
  621. println("}");
  622. println("");
  623. // Generate code for each rule in the grammar
  624. Enumeration ids = grammar.rules.elements();
  625. int ruleNum = 0;
  626. while (ids.hasMoreElements()) {
  627. GrammarSymbol sym = (GrammarSymbol)ids.nextElement();
  628. if (sym instanceof RuleSymbol) {
  629. RuleSymbol rs = (RuleSymbol)sym;
  630. genRule(rs, rs.references.size() == 0, ruleNum++);
  631. }
  632. exitIfError();
  633. }
  634. // Generate the token names
  635. genTokenStrings();
  636. if ( grammar.buildAST ) {
  637. genTokenASTNodeMap();
  638. }
  639. // Generate the bitsets used throughout the grammar
  640. genBitsets(bitsetsUsed, grammar.tokenManager.maxTokenType());
  641. // Generate the semantic predicate map for debugging
  642. if (grammar.debuggingOutput)
  643. genSemPredMap();
  644. // Close class definition
  645. println("");
  646. println("}");
  647. // Close the parser output stream
  648. currentOutput.close();
  649. currentOutput = null;
  650. }
  651. /** Generate code for the given grammar element.
  652. * @param blk The rule-reference to generate
  653. */
  654. public void gen(RuleRefElement rr) {
  655. if (DEBUG_CODE_GENERATOR) System.out.println("genRR(" + rr + ")");
  656. RuleSymbol rs = (RuleSymbol)grammar.getSymbol(rr.targetRule);
  657. if (rs == null || !rs.isDefined()) {
  658. // Is this redundant???
  659. antlrTool.error("Rule '" + rr.targetRule + "' is not defined", grammar.getFilename(), rr.getLine(), rr.getColumn());
  660. return;
  661. }
  662. if (!(rs instanceof RuleSymbol)) {
  663. // Is this redundant???
  664. antlrTool.error("'" + rr.targetRule + "' does not name a grammar rule", grammar.getFilename(), rr.getLine(), rr.getColumn());
  665. return;
  666. }
  667. genErrorTryForElement(rr);
  668. // AST value for labeled rule refs in tree walker.
  669. // This is not AST construction; it is just the input tree node value.
  670. if (grammar instanceof TreeWalkerGrammar &&
  671. rr.getLabel() != null &&
  672. syntacticPredLevel == 0) {
  673. println(rr.getLabel() + " = _t==ASTNULL ? null : " + lt1Value + ";");
  674. }
  675. // if in lexer and ! on rule ref or alt or rule, save buffer index to kill later
  676. if (grammar instanceof LexerGrammar && (!saveText || rr.getAutoGenType() == GrammarElement.AUTO_GEN_BANG)) {
  677. println("_saveIndex=text.length();");
  678. }
  679. // Process return value assignment if any
  680. printTabs();
  681. if (rr.idAssign != null) {
  682. // Warn if the rule has no return type
  683. if (rs.block.returnAction == null) {
  684. antlrTool.warning("Rule '" + rr.targetRule + "' has no return type", grammar.getFilename(), rr.getLine(), rr.getColumn());
  685. }
  686. _print(rr.idAssign + "=");
  687. }
  688. else {
  689. // Warn about return value if any, but not inside syntactic predicate
  690. if (!(grammar instanceof LexerGrammar) && syntacticPredLevel == 0 && rs.block.returnAction != null) {
  691. antlrTool.warning("Rule '" + rr.targetRule + "' returns a value", grammar.getFilename(), rr.getLine(), rr.getColumn());
  692. }
  693. }
  694. // Call the rule
  695. GenRuleInvocation(rr);
  696. // if in lexer and ! on element or alt or rule, save buffer index to kill later
  697. if (grammar instanceof LexerGrammar && (!saveText || rr.getAutoGenType() == GrammarElement.AUTO_GEN_BANG)) {
  698. println("text.setLength(_saveIndex);");
  699. }
  700. // if not in a syntactic predicate
  701. if (syntacticPredLevel == 0) {
  702. boolean doNoGuessTest = (
  703. grammar.hasSyntacticPredicate &&
  704. (
  705. grammar.buildAST && rr.getLabel() != null ||
  706. (genAST && rr.getAutoGenType() == GrammarElement.AUTO_GEN_NONE)
  707. )
  708. );
  709. if (doNoGuessTest) {
  710. // println("if (inputState.guessing==0) {");
  711. // tabs++;
  712. }
  713. if (grammar.buildAST && rr.getLabel() != null) {
  714. // always gen variable for rule return on labeled rules
  715. println(rr.getLabel() + "_AST = (" + labeledElementASTType + ")returnAST;");
  716. }
  717. if (genAST) {
  718. switch (rr.getAutoGenType()) {
  719. case GrammarElement.AUTO_GEN_NONE:
  720. // println("theASTFactory.addASTChild(currentAST, returnAST);");
  721. println("astFactory.addASTChild(currentAST, returnAST);");
  722. break;
  723. case GrammarElement.AUTO_GEN_CARET:
  724. antlrTool.error("Internal: encountered ^ after rule reference");
  725. break;
  726. default:
  727. break;
  728. }
  729. }
  730. // if a lexer and labeled, Token label defined at rule level, just set it here
  731. if (grammar instanceof LexerGrammar && rr.getLabel() != null) {
  732. println(rr.getLabel() + "=_returnToken;");
  733. }
  734. if (doNoGuessTest) {
  735. // tabs--;
  736. // println("}");
  737. }
  738. }
  739. genErrorCatchForElement(rr);
  740. }
  741. /** Generate code for the given grammar element.
  742. * @param blk The string-literal reference to generate
  743. */
  744. public void gen(StringLiteralElement atom) {
  745. if (DEBUG_CODE_GENERATOR) System.out.println("genString(" + atom + ")");
  746. // Variable declarations for labeled elements
  747. if (atom.getLabel() != null && syntacticPredLevel == 0) {
  748. println(atom.getLabel() + " = " + lt1Value + ";");
  749. }
  750. // AST
  751. genElementAST(atom);
  752. // is there a bang on the literal?
  753. boolean oldsaveText = saveText;
  754. saveText = saveText && atom.getAutoGenType() == GrammarElement.AUTO_GEN_NONE;
  755. // matching
  756. genMatch(atom);
  757. saveText = oldsaveText;
  758. // tack on tree cursor motion if doing a tree walker
  759. if (grammar instanceof TreeWalkerGrammar) {
  760. println("_t = _t.getNextSibling();");
  761. }
  762. }
  763. /** Generate code for the given grammar element.
  764. * @param blk The token-range reference to generate
  765. */
  766. public void gen(TokenRangeElement r) {
  767. genErrorTryForElement(r);
  768. if (r.getLabel() != null && syntacticPredLevel == 0) {
  769. println(r.getLabel() + " = " + lt1Value + ";");
  770. }
  771. // AST
  772. genElementAST(r);
  773. // match
  774. println("matchRange(" + r.beginText + "," + r.endText + ");");
  775. genErrorCatchForElement(r);
  776. }
  777. /** Generate code for the given grammar element.
  778. * @param blk The token-reference to generate
  779. */
  780. public void gen(TokenRefElement atom) {
  781. if (DEBUG_CODE_GENERATOR) System.out.println("genTokenRef(" + atom + ")");
  782. if (grammar instanceof LexerGrammar) {
  783. antlrTool.panic("Token reference found in lexer");
  784. }
  785. genErrorTryForElement(atom);
  786. // Assign Token value to token label variable
  787. if (atom.getLabel() != null && syntacticPredLevel == 0) {
  788. println(atom.getLabel() + " = " + lt1Value + ";");
  789. }
  790. // AST
  791. genElementAST(atom);
  792. // matching
  793. genMatch(atom);
  794. genErrorCatchForElement(atom);
  795. // tack on tree cursor motion if doing a tree walker
  796. if (grammar instanceof TreeWalkerGrammar) {
  797. println("_t = _t.getNextSibling();");
  798. }
  799. }
  800. public void gen(TreeElement t) {
  801. // save AST cursor
  802. println("AST __t" + t.ID + " = _t;");
  803. // If there is a label on the root, then assign that to the variable
  804. if (t.root.getLabel() != null) {
  805. println(t.root.getLabel() + " = _t==ASTNULL ? null :(" + labeledElementASTType + ")_t;");
  806. }
  807. // check for invalid modifiers ! and ^ on tree element roots
  808. if ( t.root.getAutoGenType() == GrammarElement.AUTO_GEN_BANG ) {
  809. antlrTool.error("Suffixing a root node with '!' is not implemented",
  810. grammar.getFilename(), t.getLine(), t.getColumn());
  811. t.root.setAutoGenType(GrammarElement.AUTO_GEN_NONE);
  812. }
  813. if ( t.root.getAutoGenType() == GrammarElement.AUTO_GEN_CARET ) {
  814. antlrTool.warning("Suffixing a root node with '^' is redundant; already a root",
  815. grammar.getFilename(), t.getLine(), t.getColumn());
  816. t.root.setAutoGenType(GrammarElement.AUTO_GEN_NONE);
  817. }
  818. // Generate AST variables
  819. genElementAST(t.root);
  820. if (grammar.buildAST) {
  821. // Save the AST construction state
  822. println("ASTPair __currentAST" + t.ID + " = currentAST.copy();");
  823. // Make the next item added a child of the TreeElement root
  824. println("currentAST.root = currentAST.child;");
  825. println("currentAST.child = null;");
  826. }
  827. // match root
  828. if ( t.root instanceof WildcardElement ) {
  829. println("if ( _t==null ) throw new MismatchedTokenException();");
  830. }
  831. else {
  832. genMatch(t.root);
  833. }
  834. // move to list of children
  835. println("_t = _t.getFirstChild();");
  836. // walk list of children, generating code for each
  837. for (int i = 0; i < t.getAlternatives().size(); i++) {
  838. Alternative a = t.getAlternativeAt(i);
  839. AlternativeElement e = a.head;
  840. while (e != null) {
  841. e.generate();
  842. e = e.next;
  843. }
  844. }
  845. if (grammar.buildAST) {
  846. // restore the AST construction state to that just after the
  847. // tree root was added
  848. println("currentAST = __currentAST" + t.ID + ";");
  849. }
  850. // restore AST cursor
  851. println("_t = __t" + t.ID + ";");
  852. // move cursor to sibling of tree just parsed
  853. println("_t = _t.getNextSibling();");
  854. }
  855. /** Generate the tree-parser Java file */
  856. public void gen(TreeWalkerGrammar g) throws IOException {
  857. // SAS: debugging stuff removed for now...
  858. setGrammar(g);
  859. if (!(grammar instanceof TreeWalkerGrammar)) {
  860. antlrTool.panic("Internal error generating tree-walker");
  861. }
  862. // Open the output stream for the parser and set the currentOutput
  863. // SAS: move file open to method so subclass can override it
  864. // (mainly for VAJ interface)
  865. setupOutput(grammar.getClassName());
  866. genAST = grammar.buildAST;
  867. tabs = 0;
  868. // Generate the header common to all output files.
  869. genHeader();
  870. // Do not use printAction because we assume tabs==0
  871. println(behavior.getHeaderAction(""));
  872. // Generate header for the parser
  873. println("import antlr." + grammar.getSuperClass() + ";");
  874. println("import antlr.Token;");
  875. println("import antlr.collections.AST;");
  876. println("import antlr.RecognitionException;");
  877. println("import antlr.ANTLRException;");
  878. println("import antlr.NoViableAltException;");
  879. println("import antlr.MismatchedTokenException;");
  880. println("import antlr.SemanticException;");
  881. println("import antlr.collections.impl.BitSet;");
  882. println("import antlr.ASTPair;");
  883. println("import antlr.collections.impl.ASTArray;");
  884. // Output the user-defined parser premamble
  885. println(grammar.preambleAction.getText());
  886. // Generate parser class definition
  887. String sup = null;
  888. if (grammar.superClass != null) {
  889. sup = grammar.superClass;
  890. }
  891. else {
  892. sup = "antlr." + grammar.getSuperClass();
  893. }
  894. println("");
  895. // print javadoc comment if any
  896. if (grammar.comment != null) {
  897. _println(grammar.comment);
  898. }
  899. // get prefix (replaces "public" and lets user specify)
  900. String prefix = "public";
  901. Token tprefix = (Token)grammar.options.get("classHeaderPrefix");
  902. if (tprefix != null) {
  903. String p = StringUtils.stripFrontBack(tprefix.getText(), "\"", "\"");
  904. if (p != null) {
  905. prefix = p;
  906. }
  907. }
  908. print(prefix+" ");
  909. print("class " + grammar.getClassName() + " extends " + sup);
  910. println(" implements " + grammar.tokenManager.getName() + TokenTypesFileSuffix);
  911. Token tsuffix = (Token)grammar.options.get("classHeaderSuffix");
  912. if (tsuffix != null) {
  913. String suffix = StringUtils.stripFrontBack(tsuffix.getText(), "\"", "\"");
  914. if (suffix != null) {
  915. print(", " + suffix); // must be an interface name for Java
  916. }
  917. }
  918. println(" {");
  919. // Generate user-defined parser class members
  920. print(
  921. processActionForSpecialSymbols(grammar.classMemberAction.getText(), grammar.classMemberAction.getLine(), currentRule, null)
  922. );
  923. // Generate default parser class constructor
  924. println("public " + grammar.getClassName() + "() {");
  925. tabs++;
  926. println("tokenNames = _tokenNames;");
  927. tabs--;
  928. println("}");
  929. println("");
  930. // Generate code for each rule in the grammar
  931. Enumeration ids = grammar.rules.elements();
  932. int ruleNum = 0;
  933. String ruleNameInits = "";
  934. while (ids.hasMoreElements()) {
  935. GrammarSymbol sym = (GrammarSymbol)ids.nextElement();
  936. if (sym instanceof RuleSymbol) {
  937. RuleSymbol rs = (RuleSymbol)sym;
  938. genRule(rs, rs.references.size() == 0, ruleNum++);
  939. }
  940. exitIfError();
  941. }
  942. // Generate the token names
  943. genTokenStrings();
  944. // Generate the bitsets used throughout the grammar
  945. genBitsets(bitsetsUsed, grammar.tokenManager.maxTokenType());
  946. // Close class definition
  947. println("}");
  948. println("");
  949. // Close the parser output stream
  950. currentOutput.close();
  951. currentOutput = null;
  952. }
  953. /** Generate code for the given grammar element.
  954. * @param wc The wildcard element to generate
  955. */
  956. public void gen(WildcardElement wc) {
  957. // Variable assignment for labeled elements
  958. if (wc.getLabel() != null && syntacticPredLevel == 0) {
  959. println(wc.getLabel() + " = " + lt1Value + ";");
  960. }
  961. // AST
  962. genElementAST(wc);
  963. // Match anything but EOF
  964. if (grammar instanceof TreeWalkerGrammar) {
  965. println("if ( _t==null ) throw new MismatchedTokenException();");
  966. }
  967. else if (grammar instanceof LexerGrammar) {
  968. if (grammar instanceof LexerGrammar &&
  969. (!saveText || wc.getAutoGenType() == GrammarElement.AUTO_GEN_BANG)) {
  970. println("_saveIndex=text.length();");
  971. }
  972. println("matchNot(EOF_CHAR);");
  973. if (grammar instanceof LexerGrammar &&
  974. (!saveText || wc.getAutoGenType() == GrammarElement.AUTO_GEN_BANG)) {
  975. println("text.setLength(_saveIndex);"); // kill text atom put in buffer
  976. }
  977. }
  978. else {
  979. println("matchNot(" + getValueString(Token.EOF_TYPE) + ");");
  980. }
  981. // tack on tree cursor motion if doing a tree walker
  982. if (grammar instanceof TreeWalkerGrammar) {
  983. println("_t = _t.getNextSibling();");
  984. }
  985. }
  986. /** Generate code for the given grammar element.
  987. * @param blk The (...)* block to generate
  988. */
  989. public void gen(ZeroOrMoreBlock blk) {
  990. if (DEBUG_CODE_GENERATOR) System.out.println("gen*(" + blk + ")");
  991. println("{");
  992. genBlockPreamble(blk);
  993. String label;
  994. if (blk.getLabel() != null) {
  995. label = blk.getLabel();
  996. }
  997. else {
  998. label = "_loop" + blk.ID;
  999. }
  1000. println(label + ":");
  1001. println("do {");
  1002. tabs++;
  1003. // generate the init action for ()* inside the loop
  1004. // this allows us to do usefull EOF checking...
  1005. genBlockInitAction(blk);
  1006. // Tell AST generation to build subrule result
  1007. String saveCurrentASTResult = currentASTResult;
  1008. if (blk.getLabel() != null) {
  1009. currentASTResult = blk.getLabel();
  1010. }
  1011. boolean ok = grammar.theLLkAnalyzer.deterministic(blk);
  1012. // generate exit test if greedy set to false
  1013. // and an alt is ambiguous with exit branch
  1014. // or when lookahead derived purely from end-of-file
  1015. // Lookahead analysis stops when end-of-file is hit,
  1016. // returning set {epsilon}. Since {epsilon} is not
  1017. // ambig with any real tokens, no error is reported
  1018. // by deterministic() routines and we have to check
  1019. // for the case where the lookahead depth didn't get
  1020. // set to NONDETERMINISTIC (this only happens when the
  1021. // FOLLOW contains real atoms + epsilon).
  1022. boolean generateNonGreedyExitPath = false;
  1023. int nonGreedyExitDepth = grammar.maxk;
  1024. if (!blk.greedy &&
  1025. blk.exitLookaheadDepth <= grammar.maxk &&
  1026. blk.exitCache[blk.exitLookaheadDepth].containsEpsilon()) {
  1027. generateNonGreedyExitPath = true;
  1028. nonGreedyExitDepth = blk.exitLookaheadDepth;
  1029. }
  1030. else if (!blk.greedy &&
  1031. blk.exitLookaheadDepth == LLkGrammarAnalyzer.NONDETERMINISTIC) {
  1032. generateNonGreedyExitPath = true;
  1033. }
  1034. if (generateNonGreedyExitPath) {
  1035. if (DEBUG_CODE_GENERATOR) {
  1036. System.out.println("nongreedy (...)* loop; exit depth is " +
  1037. blk.exitLookaheadDepth);
  1038. }
  1039. String predictExit =
  1040. getLookaheadTestExpression(blk.exitCache,
  1041. nonGreedyExitDepth);
  1042. println("// nongreedy exit test");
  1043. println("if (" + predictExit + ") break " + label + ";");
  1044. }
  1045. JavaBlockFinishingInfo howToFinish = genCommonBlock(blk, false);
  1046. genBlockFinish(howToFinish, "break " + label + ";");
  1047. tabs--;
  1048. println("} while (true);");
  1049. println("}");
  1050. // Restore previous AST generation
  1051. currentASTResult = saveCurrentASTResult;
  1052. }
  1053. /** Generate an alternative.
  1054. * @param alt The alternative to generate
  1055. * @param blk The block to which the alternative belongs
  1056. */
  1057. protected void genAlt(Alternative alt, AlternativeBlock blk) {
  1058. // Save the AST generation state, and set it to that of the alt
  1059. boolean savegenAST = genAST;
  1060. genAST = genAST && alt.getAutoGen();
  1061. boolean oldsaveTest = saveText;
  1062. saveText = saveText && alt.getAutoGen();
  1063. // Reset the variable name map for the alternative
  1064. Hashtable saveMap = treeVariableMap;
  1065. treeVariableMap = new Hashtable();
  1066. // Generate try block around the alt for error handling
  1067. if (alt.exceptionSpec != null) {
  1068. println("try { // for error handling");
  1069. tabs++;
  1070. }
  1071. AlternativeElement elem = alt.head;
  1072. while (!(elem instanceof BlockEndElement)) {
  1073. elem.generate(); // alt can begin with anything. Ask target to gen.
  1074. elem = elem.next;
  1075. }
  1076. if (genAST) {
  1077. if (blk instanceof RuleBlock) {
  1078. // Set the AST return value for the rule
  1079. RuleBlock rblk = (RuleBlock)blk;
  1080. if (grammar.hasSyntacticPredicate) {
  1081. // println("if ( inputState.guessing==0 ) {");
  1082. // tabs++;
  1083. }
  1084. println(rblk.getRuleName() + "_AST = (" + labeledElementASTType + ")currentAST.root;");
  1085. if (grammar.hasSyntacticPredicate) {
  1086. // --tabs;
  1087. // println("}");
  1088. }
  1089. }
  1090. else if (blk.getLabel() != null) {
  1091. // ### future: also set AST value for labeled subrules.
  1092. // println(blk.getLabel() + "_AST = ("+labeledElementASTType+")currentAST.root;");
  1093. antlrTool.warning("Labeled subrules not yet supported", grammar.getFilename(), blk.getLine(), blk.getColumn());
  1094. }
  1095. }
  1096. if (alt.exceptionSpec != null) {
  1097. // close try block
  1098. tabs--;
  1099. println("}");
  1100. genErrorHandler(alt.exceptionSpec);
  1101. }
  1102. genAST = savegenAST;
  1103. saveText = oldsaveTest;
  1104. treeVariableMap = saveMap;
  1105. }
  1106. /** Generate all the bitsets to be used in the parser or lexer
  1107. * Generate the raw bitset data like "long _tokenSet1_data[] = {...};"
  1108. * and the BitSet object declarations like "BitSet _tokenSet1 = new BitSet(_tokenSet1_data);"
  1109. * Note that most languages do not support object initialization inside a
  1110. * class definition, so other code-generators may have to separate the
  1111. * bitset declarations from the initializations (e.g., put the initializations
  1112. * in the generated constructor instead).
  1113. * @param bitsetList The list of bitsets to generate.
  1114. * @param maxVocabulary Ensure that each generated bitset can contain at least this value.
  1115. */
  1116. protected void genBitsets(Vector bitsetList,
  1117. int maxVocabulary
  1118. ) {
  1119. println("");
  1120. for (int i = 0; i < bitsetList.size(); i++) {
  1121. BitSet p = (BitSet)bitsetList.elementAt(i);
  1122. // Ensure that generated BitSet is large enough for vocabulary
  1123. p.growToInclude(maxVocabulary);
  1124. genBitSet(p, i);
  1125. }
  1126. }
  1127. /** Do something simple like:
  1128. * private static final long[] mk_tokenSet_0() {
  1129. * long[] data = { -2305839160922996736L, 63L, 16777216L, 0L, 0L, 0L };
  1130. * return data;
  1131. * }
  1132. * public static final BitSet _tokenSet_0 = new BitSet(mk_tokenSet_0());
  1133. *
  1134. * Or, for large bitsets, optimize init so ranges are collapsed into loops.
  1135. * This is most useful for lexers using unicode.
  1136. */
  1137. private void genBitSet(BitSet p, int id) {
  1138. // initialization data
  1139. println(
  1140. "private static final long[] mk" + getBitsetName(id) + "() {"
  1141. );
  1142. int n = p.lengthInLongWords();
  1143. if ( n<BITSET_OPTIMIZE_INIT_THRESHOLD ) {
  1144. println("\tlong[] data = { " + p.toStringOfWords() + "};");
  1145. }
  1146. else {
  1147. // will init manually, allocate space then set values
  1148. println("\tlong[] data = new long["+n+"];");
  1149. long[] elems = p.toPackedArray();
  1150. for (int i = 0; i < elems.length;) {
  1151. if ( elems[i]==0 ) {
  1152. // done automatically by Java, don't waste time/code
  1153. i++;
  1154. continue;
  1155. }
  1156. if ( (i+1)==elems.length || elems[i]!=elems[i+1] ) {
  1157. // last number or no run of numbers, just dump assignment

Large files files are truncated, but you can click here to view the full file