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

📄 javacodegenerator.java

📁 SRI international 发布的OAA框架软件
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
package antlr_oaa;

/* ANTLR Translator Generator
 * Project led by Terence Parr at http://www.jGuru.com
 * Software rights: http://www.antlr.org/RIGHTS.html
 *
 * $Id: JavaCodeGenerator.java,v 1.1 2002/11/08 17:37:57 agno Exp $
 */

import java.util.Enumeration;
import java.util.Hashtable;
import antlr_oaa.collections.impl.BitSet;
import antlr_oaa.collections.impl.Vector;
import java.io.PrintWriter; //SAS: changed for proper text file io
import java.io.IOException;
import java.io.FileWriter;

/**Generate MyParser.java, MyLexer.java and MyParserTokenTypes.java */
public class JavaCodeGenerator extends CodeGenerator {
    // non-zero if inside syntactic predicate generation
    protected int syntacticPredLevel = 0;
	
    // Are we generating ASTs (for parsers and tree parsers) right now?
    protected boolean genAST = false;

    // Are we saving the text consumed (for lexers) right now?
    protected boolean saveText = false;

    // Grammar parameters set up to handle different grammar classes.
    // These are used to get instanceof tests out of code generation
    String labeledElementType;
    String labeledElementASTType;
    String labeledElementInit;
    String commonExtraArgs;
    String commonExtraParams;
    String commonLocalVars;
    String lt1Value;
    String exceptionThrown;
    String throwNoViable;

    /** Tracks the rule being generated.  Used for mapTreeId */
    RuleBlock currentRule;

    /** Tracks the rule or labeled subrule being generated.  Used for
        AST generation. */
    String currentASTResult;

    /** Mapping between the ids used in the current alt, and the
     * names of variables used to represent their AST values.
     */
    Hashtable treeVariableMap = new Hashtable();

    /* Count of unnamed generated variables */
    int astVarNumber = 1;

    /** Special value used to mark duplicate in treeVariableMap */
    protected static final String NONUNIQUE = new String();

    public static final int caseSizeThreshold = 127; // ascii is max

    private Vector semPreds;

    /** Create a Java code-generator using the given Grammar.
	 * The caller must still call setTool, setBehavior, and setAnalyzer
	 * before generating code.
	 */
    public JavaCodeGenerator() {
	super();
	charFormatter = new JavaCharFormatter();
    }
    /** Adds a semantic predicate string to the sem pred vector
	    These strings will be used to build an array of sem pred names
	    when building a debugging parser.  This method should only be
	    called when the debug option is specified
	 */
    protected int addSemPred(String predicate) {
	semPreds.appendElement(predicate);
	return semPreds.size()-1;
    }
    public void exitIfError() {
	if (tool.hasError) {
	    System.out.println("Exiting due to errors.");
	    System.exit(1);
	}
    }
    /**Generate the parser, lexer, treeparser, and token types in Java */
    public void gen() {
	// Do the code generation
	try {
	    // Loop over all grammars
	    Enumeration grammarIter = behavior.grammars.elements();
	    while (grammarIter.hasMoreElements()) {
		Grammar g = (Grammar)grammarIter.nextElement();
				// Connect all the components to each other
		g.setGrammarAnalyzer(analyzer);
		g.setCodeGenerator(this);
		analyzer.setGrammar(g);
				// To get right overloading behavior across hetrogeneous grammars
		setupGrammarParameters(g);
		g.generate();
				// print out the grammar with lookahead sets (and FOLLOWs)
				// System.out.print(g.toString());
		exitIfError();
	    }

	    // Loop over all token managers (some of which are lexers)
	    Enumeration tmIter = behavior.tokenManagers.elements();
	    while (tmIter.hasMoreElements()) {
		TokenManager tm = (TokenManager)tmIter.nextElement();
		if (!tm.isReadOnly()) {
		    // Write the token manager tokens as Java
		    // this must appear before genTokenInterchange so that
		    // labels are set on string literals
		    genTokenTypes(tm);
		    // Write the token manager tokens as plain text
		    genTokenInterchange(tm);
		}
		exitIfError();
	    }
	}
	catch (IOException e) {
	    System.out.println(e.getMessage());
	}
    }
    /** Generate code for the given grammar element.
	 * @param blk The {...} action to generate
	 */
    public void gen(ActionElement action) {
	if ( DEBUG_CODE_GENERATOR ) System.out.println("genAction("+action+")");
	if ( action.isSemPred ) {
	    genSemPred(action.actionText, action.line);
	}
	else {
	    if ( grammar.hasSyntacticPredicate ) {
		println("if ( inputState.guessing==0 ) {");
		tabs++;
	    }

	    ActionTransInfo tInfo = new ActionTransInfo();
	    String actionStr = processActionForTreeSpecifiers(action.actionText, action.getLine(), currentRule, tInfo);
			
	    if ( tInfo.refRuleRoot!=null ) {
				// Somebody referenced "#rule", make sure translated var is valid
				// assignment to #rule is left as a ref also, meaning that assignments
				// with no other refs like "#rule = foo();" still forces this code to be
				// generated (unnecessarily).
		println(tInfo.refRuleRoot + " = ("+labeledElementASTType+")currentAST.root;");
	    }
			
	    // dump the translated action
	    printAction(actionStr);
			
	    if ( tInfo.assignToRoot ) {
				// Somebody did a "#rule=", reset internal currentAST.root
		println("currentAST.root = "+tInfo.refRuleRoot+";");
				// reset the child pointer too to be last sibling in sibling list
		println("currentAST.child = "+tInfo.refRuleRoot+"!=null &&"+tInfo.refRuleRoot+".getFirstChild()!=null ?");
		tabs++;
		println(tInfo.refRuleRoot+".getFirstChild() : "+tInfo.refRuleRoot+";");				
		tabs--;
		println("currentAST.advanceChildToEnd();");
	    }
			
	    if ( grammar.hasSyntacticPredicate ) {
		tabs--;
		println("}");
	    }
	}
    }
    /** Generate code for the given grammar element.
	 * @param blk The "x|y|z|..." block to generate
	 */
    public void gen(AlternativeBlock blk) {
	if ( DEBUG_CODE_GENERATOR ) System.out.println("gen("+blk+")");
	println("{");
	genBlockPreamble(blk);

	// Tell AST generation to build subrule result
	String saveCurrentASTResult = currentASTResult;
	if (blk.getLabel() != null) {
	    currentASTResult = blk.getLabel();
	}

	boolean ok = grammar.theLLkAnalyzer.deterministic(blk);
		
	JavaBlockFinishingInfo howToFinish = genCommonBlock(blk, true);
	genBlockFinish(howToFinish, throwNoViable);

	println("}");

	// Restore previous AST generation
	currentASTResult = saveCurrentASTResult;
    }
    /** Generate code for the given grammar element.
	 * @param blk The block-end element to generate.  Block-end
	 * elements are synthesized by the grammar parser to represent
	 * the end of a block.
	 */
    public void gen(BlockEndElement end) {
	if ( DEBUG_CODE_GENERATOR ) System.out.println("genRuleEnd("+end+")");
    }
    /** Generate code for the given grammar element.
	 * @param blk The character literal reference to generate
	 */
    public void gen(CharLiteralElement atom) {
	if ( DEBUG_CODE_GENERATOR ) System.out.println("genChar("+atom+")");
		
	if ( atom.getLabel()!=null ) {
	    println(atom.getLabel() + " = " + lt1Value + ";");
	}
		
	boolean oldsaveText = saveText;
	saveText = saveText && atom.getAutoGenType()==GrammarElement.AUTO_GEN_NONE;
	genMatch(atom);
	saveText = oldsaveText;
    }
    /** Generate code for the given grammar element.
	 * @param blk The character-range reference to generate
	 */
    public void gen(CharRangeElement r) {
	if ( r.getLabel()!=null  && syntacticPredLevel == 0) {
	    println(r.getLabel() + " = " + lt1Value + ";");
	}
	println("matchRange("+r.beginText+","+r.endText+");");
    }
    /** Generate the lexer Java file */
    public  void gen(LexerGrammar g) throws IOException {
	// If debugging, create a new sempred vector for this grammar
	if (g.debuggingOutput)
	    semPreds = new Vector();
			
	setGrammar(g);
	if (!(grammar instanceof LexerGrammar)) {
	    tool.panic("Internal error generating lexer");
	}

	// SAS: moved output creation to method so a subclass can change
	//      how the output is generated (for VAJ interface)
	setupOutput(grammar.getClassName());

	genAST = false;	// no way to gen trees.
	saveText = true;	// save consumed characters.

	tabs=0;

	// Generate header common to all Java output files
	genHeader();
	// Do not use printAction because we assume tabs==0
	println(behavior.getHeaderAction(""));

	// Generate header specific to lexer Java file
	// println("import java.io.FileInputStream;");
	println("import java.io.InputStream;");
	println("import antlr_oaa.TokenStreamException;");
	println("import antlr_oaa.TokenStreamIOException;");
	println("import antlr_oaa.TokenStreamRecognitionException;");
	println("import antlr_oaa.CharStreamException;");
	println("import antlr_oaa.CharStreamIOException;");
	println("import antlr_oaa.ANTLRException;");
	println("import java.io.Reader;");
	println("import java.util.Hashtable;");
	println("import antlr_oaa." + grammar.getSuperClass() + ";");
	println("import antlr_oaa.InputBuffer;");
	println("import antlr_oaa.ByteBuffer;");
	println("import antlr_oaa.CharBuffer;");
	println("import antlr_oaa.Token;");
	println("import antlr_oaa.CommonToken;");
	println("import antlr_oaa.RecognitionException;");
	println("import antlr_oaa.NoViableAltForCharException;");
	println("import antlr_oaa.MismatchedCharException;");
	println("import antlr_oaa.TokenStream;");
	println("import antlr_oaa.ANTLRHashString;");
	println("import antlr_oaa.LexerSharedInputState;");
	println("import antlr_oaa.collections.impl.BitSet;");
	println("import antlr_oaa.SemanticException;");

	// Generate user-defined lexer file preamble
	println(grammar.preambleAction.getText());

	// Generate lexer class definition
	String sup=null;
	if ( grammar.superClass!=null ) {
	    sup = grammar.superClass;
	}
	else {
	    sup = "antlr_oaa." + grammar.getSuperClass();
	}	

	// print javadoc comment if any
	if ( grammar.comment!=null ) {
	    _println(grammar.comment);
	}
		
	print("public class " + grammar.getClassName() + " extends "+sup);
	println(" implements " + grammar.tokenManager.getName() + TokenTypesFileSuffix+", TokenStream");
	Token tsuffix = (Token)grammar.options.get("classHeaderSuffix");
	if ( tsuffix != null ) {
	    String suffix = Tool.stripFrontBack(tsuffix.getText(),"\"","\"");
	    if ( suffix != null ) {
		print(", "+suffix);	// must be an interface name for Java
	    }
	}
	println(" {");

	// Generate user-defined lexer class members
	print(
	      processActionForTreeSpecifiers(grammar.classMemberAction.getText(), 0, currentRule, null)
	      );

	//
	// Generate the constructor from InputStream, which in turn
	// calls the ByteBuffer constructor
	//
	println("public " + grammar.getClassName() + "(InputStream in) {");
	tabs++;
	println("this(new ByteBuffer(in));");
	tabs--;
	println("}");

	//
	// Generate the constructor from Reader, which in turn
	// calls the CharBuffer constructor
	//
	println("public " + grammar.getClassName() + "(Reader in) {");
	tabs++;
	println("this(new CharBuffer(in));");
	tabs--;
	println("}");

	println("public " + grammar.getClassName() + "(InputBuffer ib) {");
	tabs++;
	// if debugging, wrap the input buffer in a debugger
	if (grammar.debuggingOutput)
	    println("this(new LexerSharedInputState(new antlr_oaa.debug.DebuggingInputBuffer(ib)));");
	else
	    println("this(new LexerSharedInputState(ib));");
	tabs--;
	println("}");

	//
	// Generate the constructor from InputBuffer (char or byte)
	//
	println("public " + grammar.getClassName() + "(LexerSharedInputState state) {");
	tabs++;

	println("super(state);");
	// if debugging, set up array variables and call user-overridable
	//   debugging setup method
	if ( grammar.debuggingOutput ) {
	    println("  ruleNames  = _ruleNames;");
	    println("  semPredNames = _semPredNames;");
	    println("  setupDebugging();");
	}	

	// Generate the initialization of a hashtable
	// containing the string literals used in the lexer
	// The literals variable itself is in CharScanner
	println("literals = new Hashtable();");
	Enumeration keys = grammar.tokenManager.getTokenSymbolKeys();
	while ( keys.hasMoreElements() ) {
	    String key = (String)keys.nextElement();
	    if ( key.charAt(0) != '"' ) {
		continue;
	    }
	    TokenSymbol sym = grammar.tokenManager.getTokenSymbol(key);
	    if ( sym instanceof StringLiteralSymbol ) {
		StringLiteralSymbol s = (StringLiteralSymbol)sym;
		println("literals.put(new ANTLRHashString(" + s.getId() + ", this), new Integer(" + s.getTokenType() + "));");
	    }
	}
	tabs--;
		
	Enumeration ids;
	// Generate the setting of various generated options.
	println("caseSensitiveLiterals = " + g.caseSensitiveLiterals + ";");
	println("setCaseSensitive("+g.caseSensitive+");");
	println("}");

	// generate the rule name array for debugging
	if (grammar.debuggingOutput) {
	    println("private static final String _ruleNames[] = {");

	    ids = grammar.rules.elements();
	    int ruleNum=0;
	    while ( ids.hasMoreElements() ) {
		GrammarSymbol sym = (GrammarSymbol) ids.nextElement();
		if ( sym instanceof RuleSymbol)
		    println("  \""+((RuleSymbol)sym).getId()+"\",");
	    }
	    println("};");
	}		

	// Generate nextToken() rule.
	// nextToken() is a synthetic lexer rule that is the implicit OR of all
	// user-defined lexer rules.
	genNextToken();

	// Generate code for each rule in the lexer
	ids = grammar.rules.elements();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -