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

📄 sathercodegenerator.java

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

	// AST
	genElementAST(r);

	// match
	println("match_range( " + r.beginText + ", " + r.endText + " );");
	genErrorCatchForElement(r);
    }
    /** Generate code for the given grammar element.
	 * @param blk The token-reference to generate
	 */
    public void gen(TokenRefElement atom) {
	if ( DEBUG_CODE_GENERATOR ) System.out.println("genTokenRef("+atom+")");
	if ( grammar instanceof LexerGrammar ) {
	    tool.panic("Token reference found in lexer");
	}
	genErrorTryForElement(atom);
	// Assign Token value to token label variable
	if ( atom.getLabel()!=null && syntacticPredLevel == 0) {
	    println(atom.getLabel() + " := " + lt1Value + ";");
	}

	// AST
	genElementAST(atom);

	// matching
	genMatch(atom);
	genErrorCatchForElement(atom);

	// tack on tree cursor motion if doing a tree walker
	if (grammar instanceof TreeWalkerGrammar) {
	    println("sa_t := sa_t.next_sibling;");
	}
    }
    public void gen(TreeElement t) {
	// save AST cursor
	println("sa__t" + t.ID + " : " + labeledElementASTType + " := sa_t;");

		// If there is a label on the root, then assign that to the variable
	if (t.root.getLabel() != null) {
	    println("if ( SYS::is_eq( sa_t , AST::ASTNULL ) ) then");
	    tabs++;
	    println(t.root.getLabel() + " := void;");
	    println("else");
	    println(t.root.getLabel() + " := sa_t;");
	    println("end; -- if");
	}

	// Generate AST variables
	genElementAST(t.root);
	if (grammar.buildAST) {
	    // Save the AST construction state
	    println("sa__current_ast" + t.ID + " : ANTLR_AST_PAIR{AST} := current_ast.copy;");
	    // Make the next item added a child of the TreeElement root
	    println("current_ast.root := current_ast.child;");
	    println("current_ast.child := void;");
	}

	// match root
	genMatch(t.root);
	// move to list of children
	println("sa_t := sa_t.first_child;"); 
		
	// walk list of children, generating code for each
	for (int i=0; i<t.getAlternatives().size(); i++) {
	    Alternative a = t.getAlternativeAt(i);
	    AlternativeElement e = a.head;
	    while ( e != null ) {
		e.generate();
		e = e.next;
	    }
	}

	if (grammar.buildAST) {
	    // restore the AST construction state to that just after the
	    // tree root was added
	    println("current_ast := sa__current_ast" + t.ID + ";");
	}
	// restore AST cursor
	println("sa_t := sa__t" + t.ID + ";");
	// move cursor to sibling of tree just parsed
	println("sa_t := sa_t.next_sibling;");
    }
    /** Generate the tree-parser Java file */
    public void gen(TreeWalkerGrammar g) throws IOException {
	// SAS: debugging stuff removed for now...
	setGrammar(g);
	if (!(grammar instanceof TreeWalkerGrammar)) {
	    tool.panic("Internal error generating tree-walker");
	}
	// Open the output stream for the parser and set the currentOutput
	// SAS: move file open to method so subclass can override it
	//      (mainly for VAJ interface)
	setupOutput(grammar.getClassName());

	genAST = grammar.buildAST;
	tabs = 0;

	// Generate the header common to all output files.
	genHeader();
	// Do not use printAction because we assume tabs==0
	println(behavior.getHeaderAction(""));
		
	// Output the user-defined parser premamble
	println(grammar.preambleAction.getText());

	// Generate parser class definition
	String sup=null;
	if ( grammar.superClass!=null ) {
	    sup = grammar.superClass.toUpperCase();
	}
	else {
	    sup = "ANTLR_TREE_PARSER";
	}	

	// print javadoc comment if any
	if ( grammar.comment!=null ) {
	    _println(grammar.comment);
	}
		
	println("class " + grammar.getClassName() + "{AST < $ANTLR_AST{AST} } is" );
	println("");
	tabs++;

	println("include " + sup + "{" + labeledElementASTType + "} create -> tree_parser_create;" );
	println("include " + grammar.tokenManager.getName() + "_" 
		+ TokenTypesFileSuffix.toUpperCase() + ";" );
	println("");

	/*
	  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
	  }
	  }
	*/

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

	println("attr token_names : ARRAY{STR};");
	println("");

	// Generate default parser class constructor
	println("create : SAME is" );
	tabs++;
	println("res : SAME := tree_parser_create;");
	println("res.token_names := sa_token_names;");
	println("return res;");
	tabs--;
	println("end; -- create");
	println("");

	// Generate code for each rule in the grammar
	Enumeration ids = grammar.rules.elements();
	int ruleNum=0;
	String ruleNameInits = "";
	while ( ids.hasMoreElements() ) {
	    GrammarSymbol sym = (GrammarSymbol) ids.nextElement();
	    if ( sym instanceof RuleSymbol) {
		RuleSymbol rs = (RuleSymbol)sym;
		genRule(rs, rs.references.size()==0, ruleNum++);
	    }
	    exitIfError();
	}

	// Generate the token names
	genTokenStrings();

	// Generate the bitsets used throughout the grammar
	genBitsets(bitsetsUsed, grammar.tokenManager.maxTokenType());

	// Close class definition
	tabs--;
	println("end; -- class");
	println("");

	// Close the parser output stream
	currentOutput.close();
	currentOutput = null;
    }
    /** Generate code for the given grammar element.
	 * @param wc The wildcard element to generate
	 */
    public void gen(WildcardElement wc) {
	// Variable assignment for labeled elements
	if (wc.getLabel()!=null && syntacticPredLevel == 0) {
	    println(wc.getLabel() + " := " + lt1Value + ";");
	}

	// AST
	genElementAST(wc);
	// Match anything but EOF
	if (grammar instanceof TreeWalkerGrammar) {
	    println("if ( void(sa_t) ) then");
	    tabs++;
	    println("raise #ANTLR_MISMATCHED_TOKEN_EXCEPTION;");
	    tabs--;
	    println("end;");
	}
	else if (grammar instanceof LexerGrammar) {
	    if ( grammar instanceof LexerGrammar &&
		 (!saveText||wc.getAutoGenType()==GrammarElement.AUTO_GEN_BANG) ) {
		println("sa_save_index := text.length;");
	    }
	    println("match_not(EOF_CHAR);");
	    if ( grammar instanceof LexerGrammar &&
		 (!saveText||wc.getAutoGenType()==GrammarElement.AUTO_GEN_BANG) ) {
		// kill text atom put in buffer
		println("text := text.substring( 0 , sa_save_index);");
	    }
	    
	}
	else {
	    println("match_not(" + getValueString(Token.EOF_TYPE) + ");");
	}
		
	// tack on tree cursor motion if doing a tree walker
	if (grammar instanceof TreeWalkerGrammar) {
	    println("sa_t := sa_t.next_sibling;");
	}
    }
    /** Generate code for the given grammar element.
	 * @param blk The (...)* block to generate
	 */
    public void gen(ZeroOrMoreBlock blk) {
	if ( DEBUG_CODE_GENERATOR ) System.out.println("gen*("+blk+")");
	//		println("{");
	genBlockPreamble(blk);
	String label;
	if ( blk.getLabel() != null ) {
	    label = blk.getLabel();
	}
	else {
	    label = "_loop" + blk.ID;
	}
	//		println(label+":");
	println("loop");
	tabs++;
	
	// Tell AST generation to build subrule result
	String saveCurrentASTResult = currentASTResult;
	if (blk.getLabel() != null) {
	    currentASTResult = blk.getLabel();
	}

	boolean ok = grammar.theLLkAnalyzer.deterministic(blk);

	// generate exit test if greedy set to false
	// and an alt is ambiguous with exit branch
	// or when lookahead derived purely from end-of-file
	// Lookahead analysis stops when end-of-file is hit,
	// returning set {epsilon}.  Since {epsilon} is not
	// ambig with any real tokens, no error is reported
	// by deterministic() routines and we have to check
	// for the case where the lookahead depth didn't get
	// set to NONDETERMINISTIC (this only happens when the
	// FOLLOW contains real atoms + epsilon).
	boolean generateNonGreedyExitPath = false;
	int nonGreedyExitDepth = grammar.maxk;

	if ( !blk.greedy &&
	     blk.exitLookaheadDepth<=grammar.maxk &&
	     blk.exitCache[blk.exitLookaheadDepth].containsEpsilon() )
	    {
		generateNonGreedyExitPath = true;
		nonGreedyExitDepth = blk.exitLookaheadDepth;
	    }
	else if ( !blk.greedy &&
		  blk.exitLookaheadDepth==LLkGrammarAnalyzer.NONDETERMINISTIC )
	    {
		generateNonGreedyExitPath = true;
	    }
	if ( generateNonGreedyExitPath ) {
	    if ( DEBUG_CODE_GENERATOR ) {
		System.out.println("nongreedy (...)* loop; exit depth is "+
				   blk.exitLookaheadDepth);
	    }
	    String predictExit =
		getLookaheadTestExpression(blk.exitCache,
					   nonGreedyExitDepth);
	    println("-- nongreedy exit test");
	    println("if ( " + predictExit + " ) then break! end; -- if");
	}

	JavaBlockFinishingInfo howToFinish = genCommonBlock(blk, false);
	genBlockFinish(howToFinish, "break!;" ); 

	tabs--;
	println("end; -- loop ");

	// Restore previous AST generation
	currentASTResult = saveCurrentASTResult;
    }
    /** Generate an alternative.
	  * @param alt  The alternative to generate
	  * @param blk The block to which the alternative belongs
	  */
    protected void genAlt(Alternative alt, AlternativeBlock blk) {
	// Save the AST generation state, and set it to that of the alt
	boolean savegenAST = genAST;
	genAST = genAST && alt.getAutoGen();

	boolean oldsaveTest = saveText;
	saveText = saveText && alt.getAutoGen();

	// Reset the variable name map for the alternative
	Hashtable saveMap = treeVariableMap;
	treeVariableMap = new Hashtable();

	// Generate try block around the alt for  error handling
	if (alt.exceptionSpec != null) {
	    println("protect -- for error handling");
	    tabs++;
	}

	AlternativeElement elem = alt.head;
	while ( !(elem instanceof BlockEndElement) ) {
	    elem.generate(); // alt can begin with anything. Ask target to gen.
	    elem = elem.next;
	}

	if ( genAST) {
	    if (blk instanceof RuleBlock) {
				// Set the AST return value for the rule
		RuleBlock rblk = (RuleBlock)blk;
		println(rblk.getRuleName() + "_ast := current_ast.root;");
	    } 
	    else if (blk.getLabel() != null) {
				// ### future: also set AST value for labeled subrules.
				// println(blk.getLabel() + "_ast = ("+labeledElementASTType+")currentAST.root;");
	    }
	}

	if (alt.exceptionSpec != null) {
	    // close try block
	    tabs--;
	    genErrorHandler(alt.exceptionSpec);
	}

	genAST = savegenAST;
	saveText = oldsaveTest;

	treeVariableMap = saveMap;
    }
    /** Generate all the bitsets to be used in the parser or lexer
	 * Generate the raw bitset data like "long _tokenSet1_data[] = {...};"
	 * and the BitSet object declarations like "BitSet _tokenSet1 = new BitSet(_tokenSet1_data);"
	 * Note that most languages do not support object initialization inside a
	 * class definition, so other code-generators may have to separate the
	 * bitset declarations from the initializations (e.g., put the initializations
	 * in the generated constructor instead).
	 * @param bitsetList The list of bitsets to generate.
	 * @param maxVocabulary Ensure that each generated bitset can contain at least this value.
	 */
    protected void genBitsets(
			      Vector bitsetList,
			      int maxVocabulary
			      ) {
	    
	SatherCharFormatter satherCharFormatter = new SatherCharFormatter();

	println("");

	// here, I differ from the Java code generator.  Lexer's bitsets are implemented as 
	// Sather sets of CHAR's, Parser bitesets as Sather sets INT's

	if ( grammar instanceof LexerGrammar ) {

	    for ( int i = 0 ; i < bitsetList.size() ; i++)	{
		BitSet p = (BitSet)bitsetList.elementAt(i);
		// Ensure that generated BitSet is large enough for vocabulary
		p.growToInclude(maxVocabulary);
		String boolList = satherCharFormatter.BitSet2BoolList( p, ", " );

		String bitsetName = "sa" + getBitsetName(i);
		String bitsetData = bitsetName + "_data_";

		// initialization data
		println(
			"const " + bitsetData + 
			" : ARRAY{BOOL} := " +
			"| " +
			boolList + 
			" |;"
			);
		println( "const " + bitsetName + " : CHAR_SET := bitset( " +
			 bitsetData + " );" );
			    
	    }
	}
	else {
	    for ( int i = 0 ; i < bitsetList.size() ; i++)	{
		BitSet p = (BitSet)bitsetList.elementAt(i);
		// Ensure that generated BitSet is large enough for vocabulary
		p.growToInclude(maxVocabulary);
		String charList = satherCharFormatter.BitSet2IntList( p, ", " );

		String bitsetName = "sa" + getBitsetName(i);
		String bitsetData = bitsetName + "_data_";

		// initialization data
		println(
			"const " + bitsetData + 
			" : ARRAY{INT} := " +

⌨️ 快捷键说明

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