⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parsercodegenerator.java

📁 SkipOOMiniJOOL教学语言的编译器前端
💻 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 + -