?? genparser.java
字號:
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * This file is part of SableCC. * * See the file "LICENSE" for copyright information and the * * terms and conditions for copying, distribution and * * modification of SableCC. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */package org.sablecc.sablecc;import java.util.*;import org.sablecc.sablecc.analysis.*;import org.sablecc.sablecc.node.*;import java.io.*;import org.sablecc.sablecc.Grammar;import java.util.Vector;import java.util.Enumeration;public class GenParser extends DepthFirstAdapter{ private MacroExpander macros; private ResolveIds ids; private File pkgDir; private String pkgName; private String currentProd; private int currentAlt; private boolean hasProductions; static final int NONE = 0; static final int STAR = 1; static final int QMARK = 2; static final int PLUS = 3; int count; int elem; Map alts = new TypedTreeMap( StringComparator.instance, StringCast.instance, NodeCast.instance); public GenParser(ResolveIds ids) { this.ids = ids; try { macros = new MacroExpander( new InputStreamReader( getClass().getResourceAsStream("parser.txt"))); } catch(IOException e) { throw new RuntimeException("unable to open parser.txt."); } pkgDir = new File(ids.pkgDir, "parser"); pkgName = ids.pkgName.equals("") ? "parser" : ids.pkgName + ".parser"; if(!pkgDir.exists()) { if(!pkgDir.mkdir()) { throw new RuntimeException("Unable to create " + pkgDir.getAbsolutePath()); } } } public void caseStart(Start tree) { tree.apply(new DepthFirstAdapter() { private boolean hasAlternative; public void caseATokenDef(ATokenDef node) { String name = (String) ids.names.get(node); String errorName = (String) ids.errorNames.get(node); if(!ids.ignTokens.containsKey(name)) { Grammar.addTerminal(name, errorName); } } public void inAProd(AProd node) { hasAlternative = false; } public void inAParsedAlt(AParsedAlt node) { hasAlternative = true; } public void outAProd(AProd node) { if(hasAlternative) { Grammar.addNonterminal((String) ids.names.get(node)); } } } ); tree.getPGrammar().apply(this); if(!hasProductions) { return; } Grammar.computeLALR(); createParser(); createParserException(); createState(); createTokenIndex(); } public void inAProd(AProd node) { hasProductions = true; currentProd = (String) ids.names.get(node); } public void caseAParsedAlt(AParsedAlt node) { count = 1; node.apply(new DepthFirstAdapter() { public void inAElem(AElem node) { GenParser.this.setOut(node, new Integer(NONE)); } public void caseAStarUnOp(AStarUnOp node) { count *= 2; GenParser.this.setOut(node.parent(), new Integer(STAR)); } public void caseAQMarkUnOp(AQMarkUnOp node) { count *= 2; GenParser.this.setOut(node.parent(), new Integer(QMARK)); } public void caseAPlusUnOp(APlusUnOp node) { GenParser.this.setOut(node.parent(), new Integer(PLUS)); } } ); if(count == 1) { alts.put(ids.names.get(node), node); currentAlt = Grammar.addProduction(currentProd, (String) ids.names.get(node)); { Object temp[] = node.getElems().toArray(); for(int i = 0; i < temp.length; i++) { ((PElem) temp[i]).apply(this); } } } else { int max = count; for(count = 0; count < max; count++) { elem = 0; alts.put( "X" + (count + 1) + (String) ids.names.get(node), node); currentAlt = Grammar.addProduction(currentProd, "X" + (count + 1) + (String) ids.names.get(node)); { Object temp[] = node.getElems().toArray(); for(int i = 0; i < temp.length; i++) { ((PElem) temp[i]).apply(this); } } } } } public void caseAElem(AElem node) { int op = ((Integer) getOut(node)).intValue(); String name = (String) ids.elemTypes.get(node); switch(op) { case NONE: { Grammar.addSymbolToProduction(name, currentAlt); } break; case STAR: { // System.out.println("Star:" + count + ", " + (1 << elem)); if((count & (1 << elem)) != 0) { // System.out.println("yes"); try { Grammar.addNonterminal("X" + name); int alt = Grammar.addProduction("X" + name, "X1" + name); Grammar.addSymbolToProduction("X" + name, alt); Grammar.addSymbolToProduction(name, alt); alt = Grammar.addProduction("X" + name, "X2" + name); Grammar.addSymbolToProduction(name, alt); } catch(Exception e) {} Grammar.addSymbolToProduction("X" + name, currentAlt); } elem++; } break; case QMARK: { if((count & (1 << elem)) != 0) { Grammar.addSymbolToProduction(name, currentAlt); } elem++; } break; case PLUS: { try { Grammar.addNonterminal("X" + name); int alt = Grammar.addProduction("X" + name, "X1" + name); Grammar.addSymbolToProduction("X" + name, alt); Grammar.addSymbolToProduction(name, alt); alt = Grammar.addProduction("X" + name, "X2" + name); Grammar.addSymbolToProduction(name, alt); } catch(Exception e) {} Grammar.addSymbolToProduction("X" + name, currentAlt); } break; } } public void caseAIgnoredAlt(AIgnoredAlt node) {} private void createParser() { BufferedWriter file; try { file = new BufferedWriter( new FileWriter( new File(pkgDir, "Parser.java"))); } catch(IOException e) { throw new RuntimeException("Unable to create " + new File(pkgDir, "Parser.java").getAbsolutePath()); } try { Symbol[] terminals = Symbol.terminals(); Symbol[] nonterminals = Symbol.nonterminals(); Production[] productions = Production.productions(); macros.apply(file, "ParserHeader", new String[] {pkgName, ids.pkgName.equals("") ? "lexer" : ids.pkgName + ".lexer", ids.pkgName.equals("") ? "node" : ids.pkgName + ".node", ids.pkgName.equals("") ? "analysis" : ids.pkgName + ".analysis"}); for(int i = 0; i < (productions.length - 1); i++) { Node node = (Node) alts.get(productions[i].name); if(node == null) { macros.apply(file, "ParserReduceNoFilter", new String[] { "" + productions[i].index, "" + productions[i].leftside}); } else { macros.apply(file, "ParserReduceFilter", new String[] { "" + productions[i].index, "" + productions[i].leftside}); } } { Symbol[] rightside = productions[productions.length - 1].rightside(); macros.apply(file, "ParserParseTail", new String[] {rightside[0].name}); } for(int i = 0; i < (productions.length - 1); i++) { macros.apply(file, "ParserNewHeader", new String[] {"" + productions[i].index}); Node node = (Node) alts.get(productions[i].name); if(node == null) { Symbol[] rightside = productions[i].rightside(); for(int k = rightside.length - 1; k >= 0; k--) { macros.apply(file, "ParserNewBodyDecl", new String[] {rightside[k].name, "" + (k + 1)}); } macros.apply(file, "ParserNewBodyNew", new String[] {productions[i].name}); for(int k = 0; k < rightside.length; k++) { macros.apply(file, "ParserNewBodyParams", new String[] {(k == 0) ? "" : ", ", (k + 1) + ""}); } macros.apply(file, "ParserNewTail", new String[] { "" + productions[i].leftside}); } else { count = count(productions[i].name) - 1; elem = 0; final BufferedWriter finalFile = file; final LinkedList stack = new LinkedList(); node.apply(new DepthFirstAdapter() { private int current; public void caseAElem(AElem node) { int op = ((Integer) GenParser.this.getOut(node)).intValue(); String name = (String) ids.elemTypes.get(node); current++; switch(op) { case NONE: { stack.addFirst(new Element("ParserNewBodyDecl", new String[] {name, "" + current})); } break; case STAR: { if((count & (1 << elem)) != 0) { stack.addFirst(new Element("ParserNewBodyDecl", new String[] {"X" + name, "" + current})); } else { stack.addFirst(new Element("ParserNewBodyDeclNull", new String[] {"X" + name, "" + current})); } elem++; } break; case QMARK: { if((count & (1 << elem)) != 0) { stack.addFirst(new Element("ParserNewBodyDecl", new String[] {name, "" + current})); } else { stack.addFirst(new Element("ParserNewBodyDeclNull", new String[] {name, "" + current})); } elem++; } break; case PLUS: { stack.addFirst(new Element("ParserNewBodyDecl", new String[] {"X" + name, "" + current})); } break; } } } ); try { for(Iterator it = stack.iterator(); it.hasNext();) { Element e = (Element) it.next(); macros.apply(file, e.macro, e.arguments); } } catch(IOException e) { throw new RuntimeException("An error occured while writing to " + new File(pkgDir, "Parser.java").getAbsolutePath()); } macros.apply(file, "ParserNewBodyNew", new String[] { (node == null) ? productions[i].name : name(productions[i].name)}); node.apply(new DepthFirstAdapter() { private int current; public void caseAElem(AElem node) { try { String name = (String) ids.elemTypes.get(node);
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -