📄 parseengine.java
字号:
// there's no need to check it below for "e_nrw" and "ntexp". In // fact, we rely here on the fact that the "name" fields of both these // variables are the same. NonTerminal e_nrw = (NonTerminal)e; NormalProduction ntprod = (NormalProduction)(production_table.get(e_nrw.name)); if (ntprod instanceof JavaCodeProduction) { ; // nothing to do here } else { generate3R(ntprod.expansion, inf); } } else if (e instanceof Choice) { Choice e_nrw = (Choice)e; for (int i = 0; i < e_nrw.choices.size(); i++) { generate3R((Expansion)(e_nrw.choices.elementAt(i)), inf); } } else if (e instanceof Sequence) { Sequence e_nrw = (Sequence)e; // We skip the first element in the following iteration since it is the // Lookahead object. int cnt = inf.count; for (int i = 1; i < e_nrw.units.size(); i++) { Expansion eseq = (Expansion)(e_nrw.units.elementAt(i)); setupPhase3Builds(new Phase3Data(eseq, cnt)); cnt -= minimumSize(eseq); if (cnt <= 0) break; } } else if (e instanceof TryBlock) { TryBlock e_nrw = (TryBlock)e; setupPhase3Builds(new Phase3Data(e_nrw.exp, inf.count)); } else if (e instanceof OneOrMore) { OneOrMore e_nrw = (OneOrMore)e; generate3R(e_nrw.expansion, inf); } else if (e instanceof ZeroOrMore) { ZeroOrMore e_nrw = (ZeroOrMore)e; generate3R(e_nrw.expansion, inf); } else if (e instanceof ZeroOrOne) { ZeroOrOne e_nrw = (ZeroOrOne)e; generate3R(e_nrw.expansion, inf); } } private static String genjj_3Call(Expansion e) { if (e.internal_name.startsWith("jj_scan_token")) return e.internal_name; else return "jj_3" + e.internal_name + "()"; } static Hashtable generated = new Hashtable(); static void buildPhase3Routine(Phase3Data inf, boolean recursive_call) { Expansion e = inf.exp; Token t = null; if (e.internal_name.startsWith("jj_scan_token")) return; if (!recursive_call) { ostr.println(" " + staticOpt() + "final private boolean jj_3" + e.internal_name + "() {"); xsp_declared = false; if (Options.B("DEBUG_LOOKAHEAD") && e.parent instanceof NormalProduction) { ostr.print(" "); if (Options.B("ERROR_REPORTING")) { ostr.print("if (!jj_rescan) "); } ostr.println("trace_call(\"" + ((NormalProduction)e.parent).lhs + "(LOOKING AHEAD...)\");"); jj3_expansion = e; } else { jj3_expansion = null; } } if (e instanceof RegularExpression) { RegularExpression e_nrw = (RegularExpression)e; if (e_nrw.label.equals("")) { Object label = names_of_tokens.get(new Integer(e_nrw.ordinal)); if (label != null) { ostr.println(" if (jj_scan_token(" + (String)label + ")) " + genReturn(true)); } else { ostr.println(" if (jj_scan_token(" + e_nrw.ordinal + ")) " + genReturn(true)); } } else { ostr.println(" if (jj_scan_token(" + e_nrw.label + ")) " + genReturn(true)); } //ostr.println(" if (jj_la == 0 && jj_scanpos == jj_lastpos) " + genReturn(false)); } else if (e instanceof NonTerminal) { // All expansions of non-terminals have the "name" fields set. So // there's no need to check it below for "e_nrw" and "ntexp". In // fact, we rely here on the fact that the "name" fields of both these // variables are the same. NonTerminal e_nrw = (NonTerminal)e; NormalProduction ntprod = (NormalProduction)(production_table.get(e_nrw.name)); if (ntprod instanceof JavaCodeProduction) { ostr.println(" if (true) { jj_la = 0; jj_scanpos = jj_lastpos; " + genReturn(false) + "}"); } else { Expansion ntexp = ntprod.expansion; //ostr.println(" if (jj_3" + ntexp.internal_name + "()) " + genReturn(true)); ostr.println(" if (" + genjj_3Call(ntexp)+ ") " + genReturn(true)); //ostr.println(" if (jj_la == 0 && jj_scanpos == jj_lastpos) " + genReturn(false)); } } else if (e instanceof Choice) { if (!xsp_declared) { xsp_declared = true; ostr.println(" Token xsp;"); } ostr.println(" xsp = jj_scanpos;"); Sequence nested_seq; Choice e_nrw = (Choice)e; for (int i = 0; i < e_nrw.choices.size(); i++) { nested_seq = (Sequence)(e_nrw.choices.elementAt(i)); Lookahead la = (Lookahead)(nested_seq.units.elementAt(0)); if (la.action_tokens.size() != 0) { // We have semantic lookahead that must be evaluated. ostr.println(" lookingAhead = true;"); ostr.print(" jj_semLA = "); printTokenSetup((Token)(la.action_tokens.elementAt(0))); for (java.util.Enumeration enum = la.action_tokens.elements(); enum.hasMoreElements();) { t = (Token)enum.nextElement(); printToken(t, ostr); } printTrailingComments(t, ostr); ostr.println(";"); ostr.println(" lookingAhead = false;"); } ostr.print(" if ("); if (la.action_tokens.size() != 0) { ostr.print("!jj_semLA || "); } if (i != e_nrw.choices.size() - 1) { //ostr.println("jj_3" + nested_seq.internal_name + "()) {"); ostr.println(genjj_3Call(nested_seq) + ") {"); ostr.println(" jj_scanpos = xsp;"); } else { //ostr.println("jj_3" + nested_seq.internal_name + "()) " + genReturn(true)); ostr.println(genjj_3Call(nested_seq) + ") " + genReturn(true)); //ostr.println(" if (jj_la == 0 && jj_scanpos == jj_lastpos) " + genReturn(false)); } } for (int i = 1; i < e_nrw.choices.size(); i++) { //ostr.println(" } else if (jj_la == 0 && jj_scanpos == jj_lastpos) " + genReturn(false)); ostr.println(" }"); } } else if (e instanceof Sequence) { Sequence e_nrw = (Sequence)e; // We skip the first element in the following iteration since it is the // Lookahead object. int cnt = inf.count; for (int i = 1; i < e_nrw.units.size(); i++) { Expansion eseq = (Expansion)(e_nrw.units.elementAt(i)); buildPhase3Routine(new Phase3Data(eseq, cnt), true);//System.out.println("minimumSize: line: " + eseq.line + ", column: " + eseq.column + ": " + minimumSize(eseq));//Test Code cnt -= minimumSize(eseq); if (cnt <= 0) break; } } else if (e instanceof TryBlock) { TryBlock e_nrw = (TryBlock)e; buildPhase3Routine(new Phase3Data(e_nrw.exp, inf.count), true); } else if (e instanceof OneOrMore) { if (!xsp_declared) { xsp_declared = true; ostr.println(" Token xsp;"); } OneOrMore e_nrw = (OneOrMore)e; Expansion nested_e = e_nrw.expansion; //ostr.println(" if (jj_3" + nested_e.internal_name + "()) " + genReturn(true)); ostr.println(" if (" + genjj_3Call(nested_e) + ") " + genReturn(true)); //ostr.println(" if (jj_la == 0 && jj_scanpos == jj_lastpos) " + genReturn(false)); ostr.println(" while (true) {"); ostr.println(" xsp = jj_scanpos;"); //ostr.println(" if (jj_3" + nested_e.internal_name + "()) { jj_scanpos = xsp; break; }"); ostr.println(" if (" + genjj_3Call(nested_e) + ") { jj_scanpos = xsp; break; }"); //ostr.println(" if (jj_la == 0 && jj_scanpos == jj_lastpos) " + genReturn(false)); ostr.println(" }"); } else if (e instanceof ZeroOrMore) { if (!xsp_declared) { xsp_declared = true; ostr.println(" Token xsp;"); } ZeroOrMore e_nrw = (ZeroOrMore)e; Expansion nested_e = e_nrw.expansion; ostr.println(" while (true) {"); ostr.println(" xsp = jj_scanpos;"); //ostr.println(" if (jj_3" + nested_e.internal_name + "()) { jj_scanpos = xsp; break; }"); ostr.println(" if (" + genjj_3Call(nested_e) + ") { jj_scanpos = xsp; break; }"); //ostr.println(" if (jj_la == 0 && jj_scanpos == jj_lastpos) " + genReturn(false)); ostr.println(" }"); } else if (e instanceof ZeroOrOne) { if (!xsp_declared) { xsp_declared = true; ostr.println(" Token xsp;"); } ZeroOrOne e_nrw = (ZeroOrOne)e; Expansion nested_e = e_nrw.expansion; ostr.println(" xsp = jj_scanpos;"); //ostr.println(" if (jj_3" + nested_e.internal_name + "()) jj_scanpos = xsp;"); ostr.println(" if (" + genjj_3Call(nested_e) + ") jj_scanpos = xsp;"); //ostr.println(" else if (jj_la == 0 && jj_scanpos == jj_lastpos) " + genReturn(false)); } if (!recursive_call) { ostr.println(" " + genReturn(false)); ostr.println(" }"); ostr.println(""); } } /* * Returns the minimum number of tokens that can parse to this expansion. */ static int minimumSize(Expansion e) { int retval = 0; // should never be used. Will be bad if it is. if (e.inMinimumSize) { // recursive search for minimum size unnecessary. return Integer.MAX_VALUE; } e.inMinimumSize = true; if (e instanceof RegularExpression) { retval = 1; } else if (e instanceof NonTerminal) { NonTerminal e_nrw = (NonTerminal)e; NormalProduction ntprod = (NormalProduction)(production_table.get(e_nrw.name)); if (ntprod instanceof JavaCodeProduction) { retval = Integer.MAX_VALUE; // Make caller think this is unending (for we do not go beyond JAVACODE during // phase3 execution). } else { Expansion ntexp = ntprod.expansion; retval = minimumSize(ntexp); } } else if (e instanceof Choice) { int min = Integer.MAX_VALUE; Expansion nested_e; Choice e_nrw = (Choice)e; for (int i = 0; i < e_nrw.choices.size(); i++) { nested_e = (Expansion)(e_nrw.choices.elementAt(i)); int min1 = minimumSize(nested_e); if (min > min1) min = min1; } retval = min; } else if (e instanceof Sequence) { int min = 0; Sequence e_nrw = (Sequence)e; // We skip the first element in the following iteration since it is the // Lookahead object. for (int i = 1; i < e_nrw.units.size(); i++) { Expansion eseq = (Expansion)(e_nrw.units.elementAt(i)); int mineseq = minimumSize(eseq); if (min == Integer.MAX_VALUE || mineseq == Integer.MAX_VALUE) { min = Integer.MAX_VALUE; // Adding infinity to something results in infinity. } else { min += mineseq; } } retval = min; } else if (e instanceof TryBlock) { TryBlock e_nrw = (TryBlock)e; retval = minimumSize(e_nrw.exp); } else if (e instanceof OneOrMore) { OneOrMore e_nrw = (OneOrMore)e; retval = minimumSize(e_nrw.expansion); } else if (e instanceof ZeroOrMore) { retval = 0; } else if (e instanceof ZeroOrOne) { retval = 0; } else if (e instanceof Lookahead) { retval = 0; } else if (e instanceof Action) { retval = 0; } e.inMinimumSize = false; return retval; } static void build(java.io.PrintWriter ps) { NormalProduction p; JavaCodeProduction jp; Token t = null; ostr = ps; for (java.util.Enumeration enum = bnfproductions.elements(); enum.hasMoreElements();) { p = (NormalProduction)enum.nextElement(); if (p instanceof JavaCodeProduction) { jp = (JavaCodeProduction)p; t = (Token)(jp.return_type_tokens.elementAt(0)); printTokenSetup(t); ccol = 1; printLeadingComments(t, ostr); ostr.print(" " + staticOpt()); cline = t.beginLine; ccol = t.beginColumn; printTokenOnly(t, ostr); for (int i = 1; i < jp.return_type_tokens.size(); i++) { t = (Token)(jp.return_type_tokens.elementAt(i)); printToken(t, ostr); } printTrailingComments(t, ostr); ostr.print(" " + jp.lhs + "("); if (jp.parameter_list_tokens.size() != 0) { printTokenSetup((Token)(jp.parameter_list_tokens.elementAt(0))); for (java.util.Enumeration enum1 = jp.parameter_list_tokens.elements(); enum1.hasMoreElements();) { t = (Token)enum1.nextElement(); printToken(t, ostr); } printTrailingComments(t, ostr); } ostr.print(") throws ParseException"); for (java.util.Enumeration enum1 = jp.throws_list.elements(); enum1.hasMoreElements();) { ostr.print(", "); java.util.Vector name = (java.util.Vector)enum1.nextElement(); for (java.util.Enumeration enum2 = name.elements(); enum2.hasMoreElements();) { t = (Token)enum2.nextElement(); ostr.print(t.image); } } ostr.print(" {"); if (Options.B("DEBUG_PARSER")) { ostr.println(""); ostr.println(" trace_call(\"" + jp.lhs + "\");"); ostr.print(" try {"); } if (jp.code_tokens.size() != 0) { printTokenSetup((Token)(jp.code_tokens.elementAt(0))); cline--; for (java.util.Enumeration enum1 = jp.code_tokens.elements(); enum1.hasMoreElements();) { t = (Token)enum1.nextElement(); printToken(t, ostr); } printTrailingComments(t, ostr); } ostr.println(""); if (Options.B("DEBUG_PARSER")) { ostr.println(" } finally {"); ostr.println(" trace_return(\"" + jp.lhs + "\");"); ostr.println(" }"); } ostr.println(" }"); ostr.println(""); } else { buildPhase1Routine((BNFProduction)p); } } for (int phase2index = 0; phase2index < phase2list.size(); phase2index++) { buildPhase2Routine((Lookahead)(phase2list.elementAt(phase2index))); } int phase3index = 0; while (phase3index < phase3list.size()) { for (; phase3index < phase3list.size(); phase3index++) { setupPhase3Builds((Phase3Data)(phase3list.elementAt(phase3index))); } } for (java.util.Enumeration enum = phase3table.elements(); enum.hasMoreElements();) { buildPhase3Routine((Phase3Data)(enum.nextElement()), false); } } public static void reInit() { ostr = null; gensymindex = 0; indentamt = (int)0; jj2LA = false; phase2list = new java.util.Vector(); phase3list = new java.util.Vector(); phase3table = new java.util.Hashtable(); firstSet = null; xsp_declared = false; jj3_expansion = null; }}/* * This class stored information to pass from phase 2 to phase 3. */class Phase3Data { /* * This is the expansion to generate the jj3 method for. */ Expansion exp; /* * This is the number of tokens that can still be consumed. This * number is used to limit the number of jj3 methods generated. */ int count; Phase3Data(Expansion e, int c) { exp = e; count = c; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -