PageRenderTime 46ms CodeModel.GetById 8ms RepoModel.GetById 0ms app.codeStats 1ms

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

https://github.com/w4x/boolangstudio
Java | 793 lines | 563 code | 75 blank | 155 comment | 160 complexity | 70d4e20b8aaa237047237f7af030787a MD5 | raw file
Possible License(s): GPL-2.0
  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/DefineGrammarSymbols.java#1 $
  7. */
  8. import java.util.Hashtable;
  9. import antlr.collections.impl.BitSet;
  10. /**DefineGrammarSymbols is a behavior for the ANTLRParser that adds all
  11. * the token and rule symbols to the grammar symbol table.
  12. *
  13. * Token types are assigned to token symbols in this class also.
  14. * The token type for a token is done in the order seen (lexically).
  15. */
  16. public class DefineGrammarSymbols implements ANTLRGrammarParseBehavior {
  17. // Contains all of the defined parser and lexer Grammar's indexed by name
  18. protected Hashtable grammars = new Hashtable();
  19. // Contains all the TokenManagers indexed by name
  20. protected Hashtable tokenManagers = new Hashtable();
  21. // Current grammar (parser or lexer)
  22. protected Grammar grammar;
  23. // The tool under which this is invoked
  24. protected Tool tool;
  25. // The grammar analyzer object
  26. LLkAnalyzer analyzer;
  27. // The command-line arguments passed to the tool.
  28. // This allows each grammar to parse the arguments as it is created
  29. String[] args;
  30. // Name for default token manager does not match any valid name
  31. static final String DEFAULT_TOKENMANAGER_NAME = "*default";
  32. // Header actions apply to all parsers unless redefined
  33. // Contains all of the header actions indexed by name
  34. protected Hashtable headerActions = new Hashtable();
  35. // Place where preamble is stored until a grammar is defined
  36. Token thePreambleAction = new CommonToken(Token.INVALID_TYPE, ""); // init to empty token
  37. // The target language
  38. String language = "Java";
  39. protected int numLexers = 0;
  40. protected int numParsers = 0;
  41. protected int numTreeParsers = 0;
  42. public DefineGrammarSymbols(Tool tool_, String[] args_, LLkAnalyzer analyzer_) {
  43. tool = tool_;
  44. args = args_;
  45. analyzer = analyzer_;
  46. }
  47. public void _refStringLiteral(Token lit, Token label, int autoGenType, boolean lastInRule) {
  48. if (!(grammar instanceof LexerGrammar)) {
  49. // String literals are treated like tokens except by the lexer
  50. String str = lit.getText();
  51. if (grammar.tokenManager.getTokenSymbol(str) != null) {
  52. // string symbol is already defined
  53. return;
  54. }
  55. StringLiteralSymbol sl = new StringLiteralSymbol(str);
  56. int tt = grammar.tokenManager.nextTokenType();
  57. sl.setTokenType(tt);
  58. grammar.tokenManager.define(sl);
  59. }
  60. }
  61. /** Reference a token */
  62. public void _refToken(Token assignId,
  63. Token t,
  64. Token label,
  65. Token args,
  66. boolean inverted,
  67. int autoGenType,
  68. boolean lastInRule) {
  69. String id = t.getText();
  70. if (!grammar.tokenManager.tokenDefined(id)) {
  71. /*
  72. // RK: dish out a warning if the token was not defined before.
  73. tool.warning("Token '" + id + "' defined outside tokens section",
  74. tool.grammarFile, t.getLine(), t.getColumn());
  75. */
  76. int tt = grammar.tokenManager.nextTokenType();
  77. TokenSymbol ts = new TokenSymbol(id);
  78. ts.setTokenType(tt);
  79. grammar.tokenManager.define(ts);
  80. }
  81. }
  82. /** Abort the processing of a grammar due to syntax errors */
  83. public void abortGrammar() {
  84. if (grammar != null && grammar.getClassName() != null) {
  85. grammars.remove(grammar.getClassName());
  86. }
  87. grammar = null;
  88. }
  89. public void beginAlt(boolean doAST_) {
  90. }
  91. public void beginChildList() {
  92. }
  93. // Exception handling
  94. public void beginExceptionGroup() {
  95. }
  96. public void beginExceptionSpec(Token label) {
  97. }
  98. public void beginSubRule(Token label, Token start, boolean not) {
  99. }
  100. public void beginTree(Token tok) throws SemanticException {
  101. }
  102. /** Define a lexer or parser rule */
  103. public void defineRuleName(Token r,
  104. String access,
  105. boolean ruleAutoGen,
  106. String docComment)
  107. throws SemanticException {
  108. String id = r.getText();
  109. // if ( Character.isUpperCase(id.charAt(0)) ) {
  110. if (r.type == ANTLRTokenTypes.TOKEN_REF) {
  111. // lexer rule
  112. id = CodeGenerator.encodeLexerRuleName(id);
  113. // make sure we define it as token identifier also
  114. if (!grammar.tokenManager.tokenDefined(r.getText())) {
  115. int tt = grammar.tokenManager.nextTokenType();
  116. TokenSymbol ts = new TokenSymbol(r.getText());
  117. ts.setTokenType(tt);
  118. grammar.tokenManager.define(ts);
  119. }
  120. }
  121. RuleSymbol rs;
  122. if (grammar.isDefined(id)) {
  123. // symbol seen before?
  124. rs = (RuleSymbol)grammar.getSymbol(id);
  125. // rule just referenced or has it been defined yet?
  126. if (rs.isDefined()) {
  127. tool.error("redefinition of rule " + id, grammar.getFilename(), r.getLine(), r.getColumn());
  128. }
  129. }
  130. else {
  131. rs = new RuleSymbol(id);
  132. grammar.define(rs);
  133. }
  134. rs.setDefined();
  135. rs.access = access;
  136. rs.comment = docComment;
  137. }
  138. /** Define a token from tokens {...}.
  139. * Must be label and literal or just label or just a literal.
  140. */
  141. public void defineToken(Token tokname, Token tokliteral) {
  142. String name = null;
  143. String literal = null;
  144. if (tokname != null) {
  145. name = tokname.getText();
  146. }
  147. if (tokliteral != null) {
  148. literal = tokliteral.getText();
  149. }
  150. // System.out.println("defining " + name + " with literal " + literal);
  151. //
  152. if (literal != null) {
  153. StringLiteralSymbol sl = (StringLiteralSymbol)grammar.tokenManager.getTokenSymbol(literal);
  154. if (sl != null) {
  155. // This literal is known already.
  156. // If the literal has no label already, but we can provide
  157. // one here, then no problem, just map the label to the literal
  158. // and don't change anything else.
  159. // Otherwise, labels conflict: error.
  160. if (name == null || sl.getLabel() != null) {
  161. tool.warning("Redefinition of literal in tokens {...}: " + literal, grammar.getFilename(), tokliteral.getLine(), tokliteral.getColumn());
  162. return;
  163. }
  164. else if (name != null) {
  165. // The literal had no label, but new def does. Set it.
  166. sl.setLabel(name);
  167. // Also, map the label to the literal.
  168. grammar.tokenManager.mapToTokenSymbol(name, sl);
  169. }
  170. }
  171. // if they provide a name/label and that name/label already
  172. // exists, just hook this literal onto old token.
  173. if (name != null) {
  174. TokenSymbol ts = (TokenSymbol)grammar.tokenManager.getTokenSymbol(name);
  175. if (ts != null) {
  176. // watch out that the label is not more than just a token.
  177. // If it already has a literal attached, then: conflict.
  178. if (ts instanceof StringLiteralSymbol) {
  179. tool.warning("Redefinition of token in tokens {...}: " + name, grammar.getFilename(), tokliteral.getLine(), tokliteral.getColumn());
  180. return;
  181. }
  182. // a simple token symbol such as DECL is defined
  183. // must convert it to a StringLiteralSymbol with a
  184. // label by co-opting token type and killing old
  185. // TokenSymbol. Kill mapping and entry in vector
  186. // of token manager.
  187. // First, claim token type.
  188. int ttype = ts.getTokenType();
  189. // now, create string literal with label
  190. sl = new StringLiteralSymbol(literal);
  191. sl.setTokenType(ttype);
  192. sl.setLabel(name);
  193. // redefine this critter as a string literal
  194. grammar.tokenManager.define(sl);
  195. // make sure the label can be used also.
  196. grammar.tokenManager.mapToTokenSymbol(name, sl);
  197. return;
  198. }
  199. // here, literal was labeled but not by a known token symbol.
  200. }
  201. sl = new StringLiteralSymbol(literal);
  202. int tt = grammar.tokenManager.nextTokenType();
  203. sl.setTokenType(tt);
  204. sl.setLabel(name);
  205. grammar.tokenManager.define(sl);
  206. if (name != null) {
  207. // make the label point at token symbol too
  208. grammar.tokenManager.mapToTokenSymbol(name, sl);
  209. }
  210. }
  211. // create a token in the token manager not a literal
  212. else {
  213. if (grammar.tokenManager.tokenDefined(name)) {
  214. tool.warning("Redefinition of token in tokens {...}: " + name, grammar.getFilename(), tokname.getLine(), tokname.getColumn());
  215. return;
  216. }
  217. int tt = grammar.tokenManager.nextTokenType();
  218. TokenSymbol ts = new TokenSymbol(name);
  219. ts.setTokenType(tt);
  220. grammar.tokenManager.define(ts);
  221. }
  222. }
  223. public void endAlt() {
  224. }
  225. public void endChildList() {
  226. }
  227. public void endExceptionGroup() {
  228. }
  229. public void endExceptionSpec() {
  230. }
  231. public void endGrammar() {
  232. }
  233. /** Called after the optional options section, to compensate for
  234. * options that may not have been set.
  235. * This method is bigger than it needs to be, but is much more
  236. * clear if I delineate all the cases.
  237. */
  238. public void endOptions() {
  239. // NO VOCAB OPTIONS
  240. if (grammar.exportVocab == null && grammar.importVocab == null) {
  241. grammar.exportVocab = grammar.getClassName();
  242. // Can we get initial vocab from default shared vocab?
  243. if (tokenManagers.containsKey(DEFAULT_TOKENMANAGER_NAME)) {
  244. // Use the already-defined token manager
  245. grammar.exportVocab = DEFAULT_TOKENMANAGER_NAME;
  246. TokenManager tm = (TokenManager)tokenManagers.get(DEFAULT_TOKENMANAGER_NAME);
  247. // System.out.println("No tokenVocabulary for '" + grammar.getClassName() + "', using default '" + tm.getName() + "'");
  248. grammar.setTokenManager(tm);
  249. return;
  250. }
  251. // no shared vocab for file, make new one
  252. // System.out.println("No exportVocab for '" + grammar.getClassName() + "', creating default '" + grammar.exportVocab + "'");
  253. TokenManager tm = new SimpleTokenManager(grammar.exportVocab, tool);
  254. grammar.setTokenManager(tm);
  255. // Add the token manager to the list of token managers
  256. tokenManagers.put(grammar.exportVocab, tm);
  257. // no default vocab, so make this the default vocab
  258. tokenManagers.put(DEFAULT_TOKENMANAGER_NAME, tm);
  259. return;
  260. }
  261. // NO OUTPUT, BUT HAS INPUT VOCAB
  262. if (grammar.exportVocab == null && grammar.importVocab != null) {
  263. grammar.exportVocab = grammar.getClassName();
  264. // first make sure input!=output
  265. if (grammar.importVocab.equals(grammar.exportVocab)) {
  266. tool.warning("Grammar " + grammar.getClassName() +
  267. " cannot have importVocab same as default output vocab (grammar name); ignored.");
  268. // kill importVocab option and try again: use default vocab
  269. grammar.importVocab = null;
  270. endOptions();
  271. return;
  272. }
  273. // check to see if the vocab is already in memory
  274. // (defined by another grammar in the file). Not normal situation.
  275. if (tokenManagers.containsKey(grammar.importVocab)) {
  276. // make a copy since we'll be generating a new output vocab
  277. // and we don't want to affect this one. Set the name to
  278. // the default output vocab==classname.
  279. TokenManager tm = (TokenManager)tokenManagers.get(grammar.importVocab);
  280. // System.out.println("Duping importVocab of " + grammar.importVocab);
  281. TokenManager dup = (TokenManager)tm.clone();
  282. dup.setName(grammar.exportVocab);
  283. // System.out.println("Setting name to " + grammar.exportVocab);
  284. dup.setReadOnly(false);
  285. grammar.setTokenManager(dup);
  286. tokenManagers.put(grammar.exportVocab, dup);
  287. return;
  288. }
  289. // System.out.println("reading in vocab "+grammar.importVocab);
  290. // Must be a file, go get it.
  291. ImportVocabTokenManager tm =
  292. new ImportVocabTokenManager(grammar,
  293. grammar.importVocab + CodeGenerator.TokenTypesFileSuffix + CodeGenerator.TokenTypesFileExt,
  294. grammar.exportVocab,
  295. tool);
  296. tm.setReadOnly(false); // since renamed, can write out
  297. // Add this token manager to the list so its tokens will be generated
  298. tokenManagers.put(grammar.exportVocab, tm);
  299. // System.out.println("vocab renamed to default output vocab of "+tm.getName());
  300. // Assign the token manager to this grammar.
  301. grammar.setTokenManager(tm);
  302. // set default vocab if none
  303. if (!tokenManagers.containsKey(DEFAULT_TOKENMANAGER_NAME)) {
  304. tokenManagers.put(DEFAULT_TOKENMANAGER_NAME, tm);
  305. }
  306. return;
  307. }
  308. // OUTPUT VOCAB, BUT NO INPUT VOCAB
  309. if (grammar.exportVocab != null && grammar.importVocab == null) {
  310. // share with previous vocab if it exists
  311. if (tokenManagers.containsKey(grammar.exportVocab)) {
  312. // Use the already-defined token manager
  313. TokenManager tm = (TokenManager)tokenManagers.get(grammar.exportVocab);
  314. // System.out.println("Sharing exportVocab of " + grammar.exportVocab);
  315. grammar.setTokenManager(tm);
  316. return;
  317. }
  318. // create new output vocab
  319. // System.out.println("Creating exportVocab " + grammar.exportVocab);
  320. TokenManager tm = new SimpleTokenManager(grammar.exportVocab, tool);
  321. grammar.setTokenManager(tm);
  322. // Add the token manager to the list of token managers
  323. tokenManagers.put(grammar.exportVocab, tm);
  324. // set default vocab if none
  325. if (!tokenManagers.containsKey(DEFAULT_TOKENMANAGER_NAME)) {
  326. tokenManagers.put(DEFAULT_TOKENMANAGER_NAME, tm);
  327. }
  328. return;
  329. }
  330. // BOTH INPUT AND OUTPUT VOCAB
  331. if (grammar.exportVocab != null && grammar.importVocab != null) {
  332. // don't want input==output
  333. if (grammar.importVocab.equals(grammar.exportVocab)) {
  334. tool.error("exportVocab of " + grammar.exportVocab + " same as importVocab; probably not what you want");
  335. }
  336. // does the input vocab already exist in memory?
  337. if (tokenManagers.containsKey(grammar.importVocab)) {
  338. // make a copy since we'll be generating a new output vocab
  339. // and we don't want to affect this one.
  340. TokenManager tm = (TokenManager)tokenManagers.get(grammar.importVocab);
  341. // System.out.println("Duping importVocab of " + grammar.importVocab);
  342. TokenManager dup = (TokenManager)tm.clone();
  343. dup.setName(grammar.exportVocab);
  344. // System.out.println("Setting name to " + grammar.exportVocab);
  345. dup.setReadOnly(false);
  346. grammar.setTokenManager(dup);
  347. tokenManagers.put(grammar.exportVocab, dup);
  348. return;
  349. }
  350. // Must be a file, go get it.
  351. ImportVocabTokenManager tm =
  352. new ImportVocabTokenManager(grammar,
  353. grammar.importVocab + CodeGenerator.TokenTypesFileSuffix + CodeGenerator.TokenTypesFileExt,
  354. grammar.exportVocab,
  355. tool);
  356. tm.setReadOnly(false); // write it out as we've changed name
  357. // Add this token manager to the list so its tokens will be generated
  358. tokenManagers.put(grammar.exportVocab, tm);
  359. // Assign the token manager to this grammar.
  360. grammar.setTokenManager(tm);
  361. // set default vocab if none
  362. if (!tokenManagers.containsKey(DEFAULT_TOKENMANAGER_NAME)) {
  363. tokenManagers.put(DEFAULT_TOKENMANAGER_NAME, tm);
  364. }
  365. return;
  366. }
  367. }
  368. public void endRule(String r) {
  369. }
  370. public void endSubRule() {
  371. }
  372. public void endTree() {
  373. }
  374. public void hasError() {
  375. }
  376. public void noASTSubRule() {
  377. }
  378. public void oneOrMoreSubRule() {
  379. }
  380. public void optionalSubRule() {
  381. }
  382. public void setUserExceptions(String thr) {
  383. }
  384. public void refAction(Token action) {
  385. }
  386. public void refArgAction(Token action) {
  387. }
  388. public void refCharLiteral(Token lit, Token label, boolean inverted, int autoGenType, boolean lastInRule) {
  389. }
  390. public void refCharRange(Token t1, Token t2, Token label, int autoGenType, boolean lastInRule) {
  391. }
  392. public void refElementOption(Token option, Token value) {
  393. }
  394. public void refTokensSpecElementOption(Token tok, Token option, Token value) {
  395. }
  396. public void refExceptionHandler(Token exTypeAndName, Token action) {
  397. }
  398. // Header action applies to all parsers and lexers.
  399. public void refHeaderAction(Token name, Token act) {
  400. String key;
  401. if (name == null)
  402. key = "";
  403. else
  404. key = StringUtils.stripFrontBack(name.getText(), "\"", "\"");
  405. // FIXME: depending on the mode the inserted header actions should
  406. // be checked for sanity.
  407. if (headerActions.containsKey(key)) {
  408. if (key.equals(""))
  409. tool.error(act.getLine() + ": header action already defined");
  410. else
  411. tool.error(act.getLine() + ": header action '" + key + "' already defined");
  412. }
  413. headerActions.put(key, act);
  414. }
  415. public String getHeaderAction(String name) {
  416. Token t = (Token)headerActions.get(name);
  417. if (t == null) {
  418. return "";
  419. }
  420. return t.getText();
  421. }
  422. public void refInitAction(Token action) {
  423. }
  424. public void refMemberAction(Token act) {
  425. }
  426. public void refPreambleAction(Token act) {
  427. thePreambleAction = act;
  428. }
  429. public void refReturnAction(Token returnAction) {
  430. }
  431. public void refRule(Token idAssign,
  432. Token r,
  433. Token label,
  434. Token args,
  435. int autoGenType) {
  436. String id = r.getText();
  437. // if ( Character.isUpperCase(id.charAt(0)) ) { // lexer rule?
  438. if (r.type == ANTLRTokenTypes.TOKEN_REF) {
  439. // lexer rule?
  440. id = CodeGenerator.encodeLexerRuleName(id);
  441. }
  442. if (!grammar.isDefined(id)) {
  443. grammar.define(new RuleSymbol(id));
  444. }
  445. }
  446. public void refSemPred(Token pred) {
  447. }
  448. public void refStringLiteral(Token lit,
  449. Token label,
  450. int autoGenType,
  451. boolean lastInRule) {
  452. _refStringLiteral(lit, label, autoGenType, lastInRule);
  453. }
  454. /** Reference a token */
  455. public void refToken(Token assignId, Token t, Token label, Token args,
  456. boolean inverted, int autoGenType, boolean lastInRule) {
  457. _refToken(assignId, t, label, args, inverted, autoGenType, lastInRule);
  458. }
  459. public void refTokenRange(Token t1, Token t2, Token label, int autoGenType, boolean lastInRule) {
  460. // ensure that the DefineGrammarSymbols methods are called; otherwise a range addes more
  461. // token refs to the alternative by calling MakeGrammar.refToken etc...
  462. if (t1.getText().charAt(0) == '"') {
  463. refStringLiteral(t1, null, GrammarElement.AUTO_GEN_NONE, lastInRule);
  464. }
  465. else {
  466. _refToken(null, t1, null, null, false, GrammarElement.AUTO_GEN_NONE, lastInRule);
  467. }
  468. if (t2.getText().charAt(0) == '"') {
  469. _refStringLiteral(t2, null, GrammarElement.AUTO_GEN_NONE, lastInRule);
  470. }
  471. else {
  472. _refToken(null, t2, null, null, false, GrammarElement.AUTO_GEN_NONE, lastInRule);
  473. }
  474. }
  475. public void refTreeSpecifier(Token treeSpec) {
  476. }
  477. public void refWildcard(Token t, Token label, int autoGenType) {
  478. }
  479. /** Get ready to process a new grammar */
  480. public void reset() {
  481. grammar = null;
  482. }
  483. public void setArgOfRuleRef(Token argaction) {
  484. }
  485. /** Set the character vocabulary for a lexer */
  486. public void setCharVocabulary(BitSet b) {
  487. // grammar should enforce that this is only called for lexer
  488. ((LexerGrammar)grammar).setCharVocabulary(b);
  489. }
  490. /** setFileOption: Associate an option value with a key.
  491. * This applies to options for an entire grammar file.
  492. * @param key The token containing the option name
  493. * @param value The token containing the option value.
  494. */
  495. public void setFileOption(Token key, Token value, String filename) {
  496. if (key.getText().equals("language")) {
  497. if (value.getType() == ANTLRParser.STRING_LITERAL) {
  498. language = StringUtils.stripBack(StringUtils.stripFront(value.getText(), '"'), '"');
  499. }
  500. else if (value.getType() == ANTLRParser.TOKEN_REF || value.getType() == ANTLRParser.RULE_REF) {
  501. language = value.getText();
  502. }
  503. else {
  504. tool.error("language option must be string or identifier", filename, value.getLine(), value.getColumn());
  505. }
  506. }
  507. else if (key.getText().equals("mangleLiteralPrefix")) {
  508. if (value.getType() == ANTLRParser.STRING_LITERAL) {
  509. tool.literalsPrefix = StringUtils.stripFrontBack(value.getText(), "\"", "\"");
  510. }
  511. else {
  512. tool.error("mangleLiteralPrefix option must be string", filename, value.getLine(), value.getColumn());
  513. }
  514. }
  515. else if (key.getText().equals("upperCaseMangledLiterals")) {
  516. if (value.getText().equals("true")) {
  517. tool.upperCaseMangledLiterals = true;
  518. }
  519. else if (value.getText().equals("false")) {
  520. tool.upperCaseMangledLiterals = false;
  521. }
  522. else {
  523. grammar.antlrTool.error("Value for upperCaseMangledLiterals must be true or false", filename, key.getLine(), key.getColumn());
  524. }
  525. }
  526. else if ( key.getText().equals("namespaceStd") ||
  527. key.getText().equals("namespaceAntlr") ||
  528. key.getText().equals("genHashLines")
  529. ) {
  530. if (!language.equals("Cpp")) {
  531. tool.error(key.getText() + " option only valid for C++", filename, key.getLine(), key.getColumn());
  532. }
  533. else {
  534. if (key.getText().equals("noConstructors")) {
  535. if (!(value.getText().equals("true") || value.getText().equals("false")))
  536. tool.error("noConstructors option must be true or false", filename, value.getLine(), value.getColumn());
  537. tool.noConstructors = value.getText().equals("true");
  538. } else if (key.getText().equals("genHashLines")) {
  539. if (!(value.getText().equals("true") || value.getText().equals("false")))
  540. tool.error("genHashLines option must be true or false", filename, value.getLine(), value.getColumn());
  541. tool.genHashLines = value.getText().equals("true");
  542. }
  543. else {
  544. if (value.getType() != ANTLRParser.STRING_LITERAL) {
  545. tool.error(key.getText() + " option must be a string", filename, value.getLine(), value.getColumn());
  546. }
  547. else {
  548. if (key.getText().equals("namespaceStd"))
  549. tool.namespaceStd = value.getText();
  550. else if (key.getText().equals("namespaceAntlr"))
  551. tool.namespaceAntlr = value.getText();
  552. }
  553. }
  554. }
  555. }
  556. else if ( key.getText().equals("namespace") ) {
  557. if ( !language.equals("Cpp") && !language.equals("CSharp") && !language.equals("Boo"))
  558. {
  559. tool.error(key.getText() + " option only valid for C++ and C# (a.k.a CSharp)", filename, key.getLine(), key.getColumn());
  560. }
  561. else
  562. {
  563. if (value.getType() != ANTLRParser.STRING_LITERAL)
  564. {
  565. tool.error(key.getText() + " option must be a string", filename, value.getLine(), value.getColumn());
  566. }
  567. else {
  568. if (key.getText().equals("namespace"))
  569. tool.setNameSpace(value.getText());
  570. }
  571. }
  572. }
  573. else {
  574. tool.error("Invalid file-level option: " + key.getText(), filename, key.getLine(), value.getColumn());
  575. }
  576. }
  577. /** setGrammarOption: Associate an option value with a key.
  578. * This function forwards to Grammar.setOption for some options.
  579. * @param key The token containing the option name
  580. * @param value The token containing the option value.
  581. */
  582. public void setGrammarOption(Token key, Token value) {
  583. if (key.getText().equals("tokdef") || key.getText().equals("tokenVocabulary")) {
  584. tool.error("tokdef/tokenVocabulary options are invalid >= ANTLR 2.6.0.\n" +
  585. " Use importVocab/exportVocab instead. Please see the documentation.\n" +
  586. " The previous options were so heinous that Terence changed the whole\n" +
  587. " vocabulary mechanism; it was better to change the names rather than\n" +
  588. " subtly change the functionality of the known options. Sorry!", grammar.getFilename(), value.getLine(), value.getColumn());
  589. }
  590. else if (key.getText().equals("literal") &&
  591. grammar instanceof LexerGrammar) {
  592. tool.error("the literal option is invalid >= ANTLR 2.6.0.\n" +
  593. " Use the \"tokens {...}\" mechanism instead.",
  594. grammar.getFilename(), value.getLine(), value.getColumn());
  595. }
  596. else if (key.getText().equals("exportVocab")) {
  597. // Set the token manager associated with the parser
  598. if (value.getType() == ANTLRParser.RULE_REF || value.getType() == ANTLRParser.TOKEN_REF) {
  599. grammar.exportVocab = value.getText();
  600. }
  601. else {
  602. tool.error("exportVocab must be an identifier", grammar.getFilename(), value.getLine(), value.getColumn());
  603. }
  604. }
  605. else if (key.getText().equals("importVocab")) {
  606. if (value.getType() == ANTLRParser.RULE_REF || value.getType() == ANTLRParser.TOKEN_REF) {
  607. grammar.importVocab = value.getText();
  608. }
  609. else {
  610. tool.error("importVocab must be an identifier", grammar.getFilename(), value.getLine(), value.getColumn());
  611. }
  612. }
  613. else {
  614. // Forward all unrecognized options to the grammar
  615. grammar.setOption(key.getText(), value);
  616. }
  617. }
  618. public void setRuleOption(Token key, Token value) {
  619. }
  620. public void setSubruleOption(Token key, Token value) {
  621. }
  622. /** Start a new lexer */
  623. public void startLexer(String file, Token name, String superClass, String doc) {
  624. if (numLexers > 0) {
  625. tool.panic("You may only have one lexer per grammar file: class " + name.getText());
  626. }
  627. numLexers++;
  628. reset();
  629. //System.out.println("Processing lexer '" + name.getText() + "'");
  630. // Does the lexer already exist?
  631. Grammar g = (Grammar)grammars.get(name);
  632. if (g != null) {
  633. if (!(g instanceof LexerGrammar)) {
  634. tool.panic("'" + name.getText() + "' is already defined as a non-lexer");
  635. }
  636. else {
  637. tool.panic("Lexer '" + name.getText() + "' is already defined");
  638. }
  639. }
  640. else {
  641. // Create a new lexer grammar
  642. LexerGrammar lg = new LexerGrammar(name.getText(), tool, superClass);
  643. lg.comment = doc;
  644. lg.processArguments(args);
  645. lg.setFilename(file);
  646. grammars.put(lg.getClassName(), lg);
  647. // Use any preamble action
  648. lg.preambleAction = thePreambleAction;
  649. thePreambleAction = new CommonToken(Token.INVALID_TYPE, "");
  650. // This is now the current grammar
  651. grammar = lg;
  652. }
  653. }
  654. /** Start a new parser */
  655. public void startParser(String file, Token name, String superClass, String doc) {
  656. if (numParsers > 0) {
  657. tool.panic("You may only have one parser per grammar file: class " + name.getText());
  658. }
  659. numParsers++;
  660. reset();
  661. //System.out.println("Processing parser '" + name.getText() + "'");
  662. // Is this grammar already defined?
  663. Grammar g = (Grammar)grammars.get(name);
  664. if (g != null) {
  665. if (!(g instanceof ParserGrammar)) {
  666. tool.panic("'" + name.getText() + "' is already defined as a non-parser");
  667. }
  668. else {
  669. tool.panic("Parser '" + name.getText() + "' is already defined");
  670. }
  671. }
  672. else {
  673. // Create a new grammar
  674. grammar = new ParserGrammar(name.getText(), tool, superClass);
  675. grammar.comment = doc;
  676. grammar.processArguments(args);
  677. grammar.setFilename(file);
  678. grammars.put(grammar.getClassName(), grammar);
  679. // Use any preamble action
  680. grammar.preambleAction = thePreambleAction;
  681. thePreambleAction = new CommonToken(Token.INVALID_TYPE, "");
  682. }
  683. }
  684. /** Start a new tree-walker */
  685. public void startTreeWalker(String file, Token name, String superClass, String doc) {
  686. if (numTreeParsers > 0) {
  687. tool.panic("You may only have one tree parser per grammar file: class " + name.getText());
  688. }
  689. numTreeParsers++;
  690. reset();
  691. //System.out.println("Processing tree-walker '" + name.getText() + "'");
  692. // Is this grammar already defined?
  693. Grammar g = (Grammar)grammars.get(name);
  694. if (g != null) {
  695. if (!(g instanceof TreeWalkerGrammar)) {
  696. tool.panic("'" + name.getText() + "' is already defined as a non-tree-walker");
  697. }
  698. else {
  699. tool.panic("Tree-walker '" + name.getText() + "' is already defined");
  700. }
  701. }
  702. else {
  703. // Create a new grammar
  704. grammar = new TreeWalkerGrammar(name.getText(), tool, superClass);
  705. grammar.comment = doc;
  706. grammar.processArguments(args);
  707. grammar.setFilename(file);
  708. grammars.put(grammar.getClassName(), grammar);
  709. // Use any preamble action
  710. grammar.preambleAction = thePreambleAction;
  711. thePreambleAction = new CommonToken(Token.INVALID_TYPE, "");
  712. }
  713. }
  714. public void synPred() {
  715. }
  716. public void zeroOrMoreSubRule() {
  717. }
  718. }