/** Visit the specified nonterminal. */ public void visit(NonTerminal nt) { Production p; try { p = analyzer.lookup(nt); } catch (IllegalArgumentException x) { // Too many productions. We assume the worst. isLexical = false; return; } if (null == p) { // No such production. We assume the worst. isLexical = false; } else if (analyzer.isProcessed(p.qName)) { // If the corresponding production has already been processed, // make sure it is lexical. if (!p.getBooleanProperty(Properties.LEXICAL)) { isLexical = false; } } else if (!analyzer.isBeingWorkedOn(p.qName)) { // The production has not been processed and is not yet under // consideration. If is text-only, accept it. If it is void, // check it out. if (p.getBooleanProperty(Properties.TEXT_ONLY)) { // Nothing to do. } else if (AST.isVoid(p.type)) { dispatch(p); } else { isLexical = false; } } }
/** Visit the specified grammar. */ public void visit(Module m) { // Initialize the per-grammar state. analyzer.register(this); analyzer.init(m); // Process the productions. for (Production p : m.productions) { // Make sure that the production has not been processed // already and that it returns a string. if (analyzer.isProcessed(p.qName)) { continue; } else if (p.getBooleanProperty(Properties.TEXT_ONLY)) { mark(p); analyzer.processed(p.qName); continue; } else if (!AST.isVoid(p.type)) { analyzer.processed(p.qName); continue; } // Clear the per-production state. isLexical = true; // Process the production. analyzer.process(p); // Tabulate the results. if (isLexical) { // All visited productions are guaranteed to be lexical. for (NonTerminal nt : analyzer.working()) { // This lookup is guaranteed to work, as the production's // fully qualified name was added by visit(Production). Production p2 = analyzer.lookup(nt); mark(p2); analyzer.processed(p2.qName); } } else { // We only know that the current production is not lexical. analyzer.processed(p.qName); } } }