📄 parsercodegenerator.java
字号:
package edu.ustc.cs.minijool.parser;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.List;
import edu.ustc.cs.minijool.lab3parser.*;
import edu.ustc.cs.minijool.parser.ast.*;
/**
* Generates parser
* 为便于调试已经为不同的步骤生成了不同的ParserCode(Parser.java, SimpleParser.java,
* SimpleParserWithAction.java)。如果想重新生成,在这个文件
* 中修改成员变量className,和48行的文件名。
*/
public class ParserCodeGenerator extends DPGenericVisitor {
private PrintStream out;
private final String className = "Parser";
private int indentLevel = 0;
private final void indent(int level) {
for (int i = 0; i < level; i++) {
out.print('\t');
}
}
private final void println(String s) {
indent(indentLevel);
out.println(s);
}
// a simple test harness
public static void main(String[] args) {
ParserCodeGenerator p = new ParserCodeGenerator();
p.generate("test/MiniJOOL.mp");
}
/**
* 生成Parser文件
* @param DParFileName 文法描述文件
*/
public void generate(String filename) {
emitCode(GrammarParser.parse(filename));
}
/**
* 生成代码
* @param spec 文法描述
*/
private void emitCode(Spec spec) {
try {
out = new PrintStream(new FileOutputStream(
"edu/ustc/cs/minijool/parser/" + className + ".java"));
} catch (IOException e) {
System.out.println(e);
System.exit(-1);
}
spec.accept(this);
}
/**
* 文法描述的访问方法
*/
public boolean visit(Spec n) {
println("package edu.ustc.cs.minijool.parser;");
out.println();
println(n.getImports());
out.println();
println("/**");
println(" * This class is generated automatically by ParserCodeGenerator.");
println(" */");
println("public class " + className + " extends RDParser {");
indentLevel++;
println(n.getPrologue());
// Constructor
println("public " + className + "(Lexer lexer) {");
indentLevel++;
println("super(lexer);");
indentLevel--;
println("}");
// parse() method
println("public boolean parse() {");
indentLevel++;
indent(indentLevel);
out.print("return ");
List l = n.getProductions();
out.println(((Production)l.get(0)).getProdName().getIdentifier() + "();");
indentLevel--;
out.println("}");
for (int i = 0; i < l.size(); i++) {
((Production)l.get(i)).accept(this);
}
indentLevel--;
out.println("}");
return false;
}
/**
* 非终结符的访问方法
*/
public boolean visit(NonTerminal n) {
out.print(n.getName().getIdentifier() + "()");
return false;
}
/**
* 终结符的访问方法
*/
public boolean visit(Terminal n) {
out.print("token(Symbol."
+ n.getName().getIdentifier() + ")");
return false;
}
/**
* 空记号的访问方法
*/
public boolean visit(Epsilon n) {
out.print("tokenEpsilon()");
return false;
}
/**
* 产生式右边的访问方法
*/
public boolean visit(RightHandSide n) {
// 得到右边的终结符与非终结符,这个List的元素都是NameWithAction类型
List l = n.getTermsAndNonTerms();
for (int i = 0; i < l.size(); i++) {
indent(indentLevel);
out.print("match = match && ");
NameWithAction name = (NameWithAction)l.get(i);
name.accept(this);
out.println(';');
// 处理对应的Action代码
Action a = name.getAction();
if (a != Action.NONE) {
println("if (match) {");
out.println(a.getActionCode());
println("}");
}
}
return false;
}
/**
* 产生式的访问方法
*/
public boolean visit(Production p) {
String prodName = p.getProdName().getIdentifier();
List l = p.getRightHandSides();
int size = l.size();
// 为左边的非终结符产生对应函数
println("private boolean " + prodName + "() {");
indentLevel++;
println("int isave = next;");
println("int stackSize = getStackSize();");
for (int i = 0; i < size; i++) {
int popCount = lengthRHS(((RightHandSide)l.get(i)));
println("next = isave;");
println("setStackSize(stackSize);");
println("if (" + prodName + (i + 1) + "()) {");
indentLevel++;
println("Object o = peek(0);"); // 取得栈顶元素
println("popStack(" + popCount + ");"); // 把分析该产生式右部压入的元素退出
println("push(o);"); // 把最后一个元素重新入栈(即该产生式的属性值)
println("return true;");
indentLevel--;
println("}");
}
println("return false;");
indentLevel--;
println("}");
// 为非终结符的每个产生式生成函数
for (int i = 0; i < size; i++) {
println("private boolean " + prodName + (i + 1) + "() {");
indentLevel++;
println("boolean match = true;");
((RightHandSide)l.get(i)).accept(this);
println("return match;");
indentLevel--;
println("}");
}
return false;
}
/**
* 辅助函数,求产生式右边的长度(包括action)
* @param n 产生式右边
* @return 长度
*/
private int lengthRHS(RightHandSide n) {
List l = n.getTermsAndNonTerms();
int size = l.size();
int actions = 0;
for (int i = 0; i < size; i++) {
if (((NameWithAction)l.get(i)).getAction() != Action.NONE) {
actions++;
}
}
return size + actions;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -