📄 semanticize.java
字号:
} } else if (prod.leftExpansions[i].walkStatus == 0) { if (prodWalk(prod.leftExpansions[i])) { loopString = prod.lhs + "... --> " + loopString; if (prod.walkStatus == -2) { prod.walkStatus = 1; JavaCCErrors.semantic_error(prod, "Left recursion detected: \"" + loopString + "\""); return false; } else { prod.walkStatus = 1; return true; } } } } prod.walkStatus = 1; return false; } // Returns true to indicate an unraveling of a detected loop, // and returns false otherwise. static private boolean rexpWalk(RegularExpression rexp) { if (rexp instanceof RJustName) { RJustName jn = (RJustName)rexp; if (jn.regexpr.walkStatus == -1) { jn.regexpr.walkStatus = -2; loopString = "..." + jn.regexpr.label + "..."; // Note: Only the regexpr's of RJustName nodes and the top leve // regexpr's can have labels. Hence it is only in these cases that // the labels are checked for to be added to the loopString. return true; } else if (jn.regexpr.walkStatus == 0) { jn.regexpr.walkStatus = -1; if (rexpWalk(jn.regexpr)) { loopString = "..." + jn.regexpr.label + "... --> " + loopString; if (jn.regexpr.walkStatus == -2) { jn.regexpr.walkStatus = 1; JavaCCErrors.semantic_error(jn.regexpr, "Loop in regular expression detected: \"" + loopString + "\""); return false; } else { jn.regexpr.walkStatus = 1; return true; } } else { jn.regexpr.walkStatus = 1; return false; } } } else if (rexp instanceof RChoice) { for (java.util.Enumeration enum = ((RChoice)rexp).choices.elements(); enum.hasMoreElements();) { if (rexpWalk((RegularExpression)enum.nextElement())) { return true; } } return false; } else if (rexp instanceof RSequence) { for (java.util.Enumeration enum = ((RSequence)rexp).units.elements(); enum.hasMoreElements();) { if (rexpWalk((RegularExpression)enum.nextElement())) { return true; } } return false; } else if (rexp instanceof ROneOrMore) { return rexpWalk(((ROneOrMore)rexp).regexpr); } else if (rexp instanceof RZeroOrMore) { return rexpWalk(((RZeroOrMore)rexp).regexpr); } else if (rexp instanceof RZeroOrOne) { return rexpWalk(((RZeroOrOne)rexp).regexpr); } else if (rexp instanceof RRepetitionRange) { return rexpWalk(((RRepetitionRange)rexp).regexpr); } return false; } /** * Objects of this class are created from class Semanticize to work on * references to regular expressions from RJustName's. */ static class FixRJustNames extends JavaCCGlobals implements TreeWalkerOp { public RegularExpression root; public boolean goDeeper(Expansion e) { return true; } public void action(Expansion e) { if (e instanceof RJustName) { RJustName jn = (RJustName)e; RegularExpression rexp = (RegularExpression)named_tokens_table.get(jn.label); if (rexp == null) { JavaCCErrors.semantic_error(e, "Undefined lexical token name \"" + jn.label + "\"."); } else if (jn == root && !jn.tpContext.isExplicit && rexp.private_rexp) { JavaCCErrors.semantic_error(e, "Token name \"" + jn.label + "\" refers to a private (with a #) regular expression."); } else if (jn == root && !jn.tpContext.isExplicit && rexp.tpContext.kind != TokenProduction.TOKEN) { JavaCCErrors.semantic_error(e, "Token name \"" + jn.label + "\" refers to a non-token (SKIP, MORE, IGNORE_IN_BNF) regular expression."); } else { jn.ordinal = rexp.ordinal; jn.regexpr = rexp; } } } } static class LookaheadFixer extends JavaCCGlobals implements TreeWalkerOp { public boolean goDeeper(Expansion e) { if (e instanceof RegularExpression) { return false; } else { return true; } } public void action(Expansion e) { if (e instanceof Sequence) { if (e.parent instanceof Choice || e.parent instanceof ZeroOrMore || e.parent instanceof OneOrMore || e.parent instanceof ZeroOrOne) { return; } Sequence seq = (Sequence)e; Lookahead la = (Lookahead)(seq.units.elementAt(0)); if (!la.isExplicit) { return; } // Create a singleton choice with an empty action. Choice ch = new Choice(); ch.line = la.line; ch.column = la.column; ch.parent = seq; Sequence seq1 = new Sequence(); seq1.line = la.line; seq1.column = la.column; seq1.parent = ch; seq1.units.addElement(la); la.parent = seq1; Action act = new Action(); act.line = la.line; act.column = la.column; act.parent = seq1; seq1.units.addElement(act); ch.choices.addElement(seq1); if (la.amount != 0) { if (la.action_tokens.size() != 0) { JavaCCErrors.warning(la, "Encountered LOOKAHEAD(...) at a non-choice location. Only semantic lookahead will be considered here."); } else { JavaCCErrors.warning(la, "Encountered LOOKAHEAD(...) at a non-choice location. This will be ignored."); } } // Now we have moved the lookahead into the singleton choice. Now create // a new dummy lookahead node to replace this one at its original location. Lookahead la1 = new Lookahead(); la1.isExplicit = false; la1.line = la.line; la1.column = la.column; la1.parent = seq; // Now set the la_expansion field of la and la1 with a dummy expansion (we use EOF). la.la_expansion = new REndOfFile(); la1.la_expansion = new REndOfFile(); seq.units.setElementAt(la1, 0); seq.units.insertElementAt(ch, 1); } } } static class ProductionDefinedChecker extends JavaCCGlobals implements TreeWalkerOp { public boolean goDeeper(Expansion e) { if (e instanceof RegularExpression) { return false; } else { return true; } } public void action(Expansion e) { if (e instanceof NonTerminal) { NonTerminal nt = (NonTerminal)e; if ((nt.prod = (NormalProduction)production_table.get(nt.name)) == null) { JavaCCErrors.semantic_error(e, "Non-terminal " + nt.name + " has not been defined."); } else { nt.prod.parents.addElement(nt); } } } } static class EmptyChecker extends JavaCCGlobals implements TreeWalkerOp { public boolean goDeeper(Expansion e) { if (e instanceof RegularExpression) { return false; } else { return true; } } public void action(Expansion e) { if (e instanceof OneOrMore) { if (Semanticize.emptyExpansionExists(((OneOrMore)e).expansion)) { JavaCCErrors.semantic_error(e, "Expansion within \"(...)+\" can be matched by empty string."); } } else if (e instanceof ZeroOrMore) { if (Semanticize.emptyExpansionExists(((ZeroOrMore)e).expansion)) { JavaCCErrors.semantic_error(e, "Expansion within \"(...)*\" can be matched by empty string."); } } else if (e instanceof ZeroOrOne) { if (Semanticize.emptyExpansionExists(((ZeroOrOne)e).expansion)) { JavaCCErrors.semantic_error(e, "Expansion within \"(...)?\" can be matched by empty string."); } } } } static class LookaheadChecker extends JavaCCGlobals implements TreeWalkerOp { public boolean goDeeper(Expansion e) { if (e instanceof RegularExpression) { return false; } else if (e instanceof Lookahead) { return false; } else { return true; } } public void action(Expansion e) { if (e instanceof Choice) { if (Options.I("LOOKAHEAD") == 1 || Options.B("FORCE_LA_CHECK")) { LookaheadCalc.choiceCalc((Choice)e); } } else if (e instanceof OneOrMore) { OneOrMore exp = (OneOrMore)e; if (Options.B("FORCE_LA_CHECK") || (implicitLA(exp.expansion) && Options.I("LOOKAHEAD") == 1)) { LookaheadCalc.ebnfCalc(exp, exp.expansion); } } else if (e instanceof ZeroOrMore) { ZeroOrMore exp = (ZeroOrMore)e; if (Options.B("FORCE_LA_CHECK") || (implicitLA(exp.expansion) && Options.I("LOOKAHEAD") == 1)) { LookaheadCalc.ebnfCalc(exp, exp.expansion); } } else if (e instanceof ZeroOrOne) { ZeroOrOne exp = (ZeroOrOne)e; if (Options.B("FORCE_LA_CHECK") || (implicitLA(exp.expansion) && Options.I("LOOKAHEAD") == 1)) { LookaheadCalc.ebnfCalc(exp, exp.expansion); } } } static boolean implicitLA(Expansion exp) { if (!(exp instanceof Sequence)) { return true; } Sequence seq = (Sequence)exp; Object obj = seq.units.elementAt(0); if (!(obj instanceof Lookahead)) { return true; } Lookahead la = (Lookahead)obj; return !la.isExplicit; } } public static void reInit() { removeList = new java.util.Vector(); itemList = new java.util.Vector(); other = null; loopString = null; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -