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

编译器/解释器

开发平台:

Others

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