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

📄 sathercodegenerator.java

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

			if (((grammar instanceof ParserGrammar) || 
			     (grammar instanceof LexerGrammar)) && 
			    grammar.debuggingOutput )
			    e = "("+e+" and fireSemanticPredicateEvaluated(antlr_oaa.debug.SemanticPredicateEvent.PREDICTING,"+
				addSemPred(charFormatter.escapeString(actionStr))+","+actionStr+"))";
			else {
			    e = "("+e+" and ("+actionStr +"))";
			}
		    }

		    // Generate any syntactic predicates
		    if ( nIF>0 ) {
			if ( alt.synPred != null ) {
			    println("else");
			    tabs++;
			    genSynPred( alt.synPred, e );
			    closingBracesOfIFSequence++;
			}
			else {
			    println("elsif " + e + " then" );
			}
		    }
		    else {
			if ( alt.synPred != null ) {
			    genSynPred( alt.synPred, e );
			}
			else {
			    // when parsing trees, convert null to
			    // valid tree node with NULL lookahead.
			    if ( grammar instanceof TreeWalkerGrammar ) {
				println("if ( void(sa_t) ) then");
				tabs++;
				println("sa_t := AST::ASTNULL;");
				tabs--;
				println("end; -- if");
			    }
			    println("if " + e + " then");
			}
		    }
					
		}	

		nIF++;
		tabs++;
		genAlt(alt, blk);
		tabs--;
		if ( !defaultBlock )
		    println("end; -- if");
	    }
	}

	String ps = "";
	for (int i=1; i<=closingBracesOfIFSequence; i++) {
	    ps+="end;";
	}

	// Restore the AST generation state
	genAST = savegenAST;
		
	// restore save text state
	saveText=oldsaveTest;

	// Return the finishing info.
	if ( createdLL1Switch ) {
	    tabs--;
	    finishingInfo.postscript = ps; // + "end; -- case";
	    finishingInfo.generatedSwitch = true;
	    finishingInfo.generatedAnIf = nIF>0;
	    //return new JavaBlockFinishingInfo(ps+"}",true,nIF>0); // close up switch statement
			
	}
	else {
	    finishingInfo.postscript = ps;
	    finishingInfo.generatedSwitch = false;
	    finishingInfo.generatedAnIf = nIF>0;
	    // return new JavaBlockFinishingInfo(ps, false,nIF>0);
	}	
	return finishingInfo;
    }

    private static boolean suitableForCaseExpression(Alternative a) {
	return
	    a.lookaheadDepth == 1 &&
	    a.semPred == null &&
	    !a.cache[1].containsEpsilon() &&
	    a.cache[1].fset.degree()<=caseSizeThreshold;
    }


    /** Generate code to link an element reference into the AST */
    private void genElementAST(AlternativeElement el) {
	// handle case where you're not building trees, but are in tree walker.
	// Just need to get labels set up.
	if ( grammar instanceof TreeWalkerGrammar && !grammar.buildAST ) {
	    String elementRef;
	    String astName;

	    // Generate names and declarations of the AST variable(s)
	    if (el.getLabel() == null) {
		elementRef = lt1Value;
				// Generate AST variables for unlabeled stuff
		astName = "tmp" + astVarNumber + "_ast";
		astVarNumber++;
				// Map the generated AST variable in the alternate
		mapTreeVariable(el, astName);
				// Generate an "input" AST variable also
		println( astName + "_in : " + labeledElementASTType + " := " + elementRef + ";");
	    }
	    return;
	}

	if (grammar.buildAST && syntacticPredLevel == 0) {
	    boolean doNoGuessTest = (
				     grammar.hasSyntacticPredicate &&
				     (
				      el.getLabel() != null ||
				      el.getAutoGenType() != GrammarElement.AUTO_GEN_BANG
				      )
				     );

	    String elementRef;
	    String astName;

	    // Generate names and declarations of the AST variable(s)
	    if (el.getLabel() != null) {
		elementRef = el.getLabel();
		astName = el.getLabel() + "_ast";
	    } else {
		elementRef = lt1Value;
				// Generate AST variables for unlabeled stuff
		astName = "tmp" + astVarNumber + "_ast";
		astVarNumber++;
		// Generate the declaration (can only build AST's for atoms
		GrammarAtom ga = (GrammarAtom)el;
		if ( ga.getASTNodeType()!=null ) {
		    println( astName + " : " + ga.getASTNodeType() + " := void;");
		}
		else {
		    println( astName + " : " + labeledElementASTType + ";" );
		}

		// Map the generated AST variable in the alternate
		mapTreeVariable(el, astName);
		if (grammar instanceof TreeWalkerGrammar) {
		    // Generate an "input" AST variable also
		    println(astName + "_in : " + labeledElementASTType + ";" );
		}
	    }

	    // Enclose actions with !guessing
	    if (doNoGuessTest) {
		println("if ( input_state.guessing = 0 ) then"); 
		tabs++;
	    }

	    // we need to find out the type of argument of
	    // toke_factory::create.  Sather cannot
	    // overload function unless their signatures
	    // can clearly be disambiguated.  Therefore the 
	    // AST::create( $ANTLR_AST ) : $ANTLR_AST 
	    //   and
	    // AST::create( $ANTLR_TOKEN ) : $ANTLR_AST
	    // cannot coexist.  Therefore we rename them
	    // create_ast_from_ast and create_ast_from_token, respectively.

	    String astType = labeledElementASTType;
	    GrammarAtom atom = (GrammarAtom)el;
	    if ( atom != null && atom.getASTNodeType() != null ) {
		astType = atom.getASTNodeType();
		// make this the current AST type, used
		// for supsequent AST create's, even though
		// the may be temporary AST's
		labeledElementASTType = astType; 
	    }		

	    String astCreateString;
	    if ( grammar instanceof TreeWalkerGrammar )
		astCreateString = astType + "::create_from_ast( " + elementRef + " )";
	    else
		astCreateString = astType + "::create_from_token( " + elementRef + " )";

	    if (el.getLabel() != null) {
		println(astName + " := " + astCreateString + ";" );
	    } else {
		elementRef = lt1Value;
		println(astName + " := " + astCreateString + ";" );
		// Map the generated AST variable in the alternate
		if (grammar instanceof TreeWalkerGrammar) {
		    // set "input" AST variable also
		    println(astName + "_in := " + elementRef + ";");
		}
	    }

	    if (genAST) {
		switch (el.getAutoGenType()) {
		case GrammarElement.AUTO_GEN_NONE:
		    println("current_ast.add_child( " + astName + " );");
		    break;
		case GrammarElement.AUTO_GEN_CARET:
		    println("current_ast.make_root( " + astName + " );");
		    break;
		default:
		    break;
		}
	    }
	    if (doNoGuessTest) {
		tabs--;
		println("end; -- if?");
	    }
	}
    }
    /** Close the try block and generate catch phrases 
	 * if the element has a labeled handler in the rule 
	 */
    private void genErrorCatchForElement(AlternativeElement el) {
	if (el.getLabel() == null) return;
	String r = el.enclosingRuleName;
	if ( grammar instanceof LexerGrammar ) {
	    r = CodeGenerator.lexerRuleName(el.enclosingRuleName);
	}
	RuleSymbol rs = (RuleSymbol)grammar.getSymbol(r);
	if (rs == null) {
	    tool.panic("Enclosing rule not found!");
	}
	ExceptionSpec ex = rs.block.findExceptionSpec(el.getLabel());
	if (ex != null) {
	    tabs--;
	    println("}*28");
	    genErrorHandler(ex);
	}
    }
    /** Generate the catch phrases for a user-specified error handler */
    private void genErrorHandler(ExceptionSpec ex) {
	// Each ExceptionHandler in the ExceptionSpec is a separate catch
	for (int i = 0; i < ex.handlers.size(); i++)
	    {
		ExceptionHandler handler = (ExceptionHandler)ex.handlers.elementAt(i);
		// Generate catch phrase
		println("when " + extractTypeOfAction(handler.exceptionTypeAndName) + " then");
		tabs++;
		if (grammar.hasSyntacticPredicate) {
		    println("if ( input_state.guessing = 0 ) then");
		    tabs++;
		}
			
		// When not guessing, execute user handler action
		printAction(
			    processActionForTreeSpecifiers(handler.action.getText(), 0, currentRule, null)
			    );
				
		if (grammar.hasSyntacticPredicate) {
		    tabs--;
		    println("else");
		    tabs++;
				// When guessing, rethrow exception
		    println("raise exception");
				// extractIdOfAction(handler.exceptionTypeAndName) + ";"
		    tabs--;
		    println("end; -- if");
		}
		tabs--;
	    }
	// Close catch phrase
	println("end; -- protect");


    }
    /** Generate a try { opening if the element has a labeled handler in the rule */
    private void genErrorTryForElement(AlternativeElement el) {
	if (el.getLabel() == null) return;
	String r = el.enclosingRuleName;
	if ( grammar instanceof LexerGrammar ) {
	    r = CodeGenerator.lexerRuleName(el.enclosingRuleName);
	}
	RuleSymbol rs = (RuleSymbol)grammar.getSymbol(r);
	if (rs == null) {
	    tool.panic("Enclosing rule not found!");
	}
	ExceptionSpec ex = rs.block.findExceptionSpec(el.getLabel());
	if (ex != null) {
	    println("try { // for error handling");
	    tabs++;
	}
    }

    /** Generate a header that is common to all Sather files */
    protected void genHeader() {
	println("-- $ANTLR "+Tool.version+": "+
		"\""+Tool.fileMinusPath(tool.grammarFile)+"\""+
		" -> "+
		"\""+grammar.getClassName()+".sa\"$");
    }

    private void genLiteralsTest() {
	println("sa_ttype := test_literals_table(sa_ttype);");
    }

    private void genLiteralsTestForPartialToken() {
	println("sa_ttype := test_literals_table( text.substring( sa_begin, text.length - sa_begin ), sa_ttype );");
    }

    protected void genMatch(BitSet b) {
    }
    protected void genMatch(GrammarAtom atom) {
	if ( atom instanceof StringLiteralElement ) {
	    if ( grammar instanceof LexerGrammar ) {
		genMatchUsingAtomText(atom);
	    }
	    else {
		genMatchUsingAtomTokenType(atom);
	    }
	}
	else if ( atom instanceof CharLiteralElement ) {
	    if ( grammar instanceof LexerGrammar ) {
		genMatchUsingAtomText(atom);
	    }
	    else {
		tool.error("cannot ref character literals in grammar: "+atom);				
	    }
	}
	else if ( atom instanceof TokenRefElement ) {
	    genMatchUsingAtomText(atom);
	}
    }
    protected void genMatchUsingAtomText(GrammarAtom atom) {
	// match() for trees needs the _t cursor
	String astArgs="";
	if (grammar instanceof TreeWalkerGrammar) {
	    astArgs="sa_t,";
	}
		
	// if in lexer and ! on element, save buffer index to kill later
	if ( grammar instanceof LexerGrammar && (!saveText||atom.getAutoGenType()==GrammarElement.AUTO_GEN_BANG) ) {
	    println("sa_save_index := text.length;");
	}
		
	print(atom.not ? "match_not(" : "match(");
	_print(astArgs);
		
	// print out what to match
	if (atom.atomText.equals("EOF")) {
	    // horrible hack to handle EOF case
	    _print("ANTLR_COMMON_TOKEN::EOF_TYPE");
	} 
	else {
	    _print(atom.atomText);
	}
	_println(");");

	if ( grammar instanceof LexerGrammar && (!saveText||atom.getAutoGenType()==GrammarElement.AUTO_GEN_BANG) ) {
	    println("text := text.substring( 0 , sa_save_index);");		// kill text atom put in buffer
	}
    }
    protected void genMatchUsingAtomTokenType(GrammarAtom atom) {
	// match() for trees needs the _t cursor
	String astArgs="";
	if (grammar instanceof TreeWalkerGrammar) {
	    astArgs="sa_t,";
	}

	// If the literal can be mangled, generate the symbolic constant instead
	String mangledName = null;
	String s = astArgs + getValueString(atom.getType());

		// matching
	println( (atom.not ? "match_not(" : "match(") + s + ");");
    }

    /** Generate the nextToken() rule.  nextToken() is a synthetic
      * lexer rule that is the implicit OR of all user-defined lexer
      * rules.  
      */
    public void genNextToken() {
	// Are there any public rules?  If not, then just generate a
	// fake nextToken().
	boolean hasPublicRules = false;
	for (int i = 0; i < grammar.rules.size(); i++) {
	    RuleSymbol rs = (RuleSymbol)grammar.rules.elementAt(i);
	    if ( rs.isDefined() && rs.access.equals("public") ) {
		hasPublicRules = true;
		break;
	    }
	}
	if (!hasPublicRules) {
	    println("");
	    println("next_token : TOKEN is " );
	    tabs++;
	    println("protect");
	    tabs++;
	    println("upon_eof;");
	    tabs--;
	    println("when $ANTLR_CHAR_STREAM_EXCEPTION then");
	    tabs++;
	    println("raise #ANTLR_TOKEN_STREAM_EXCEPTION( exception.str );");
	    tabs--;
	    println("end; -- protect");
	    println("return #ANTLR_COMMON_TOKEN( ANTLR_COMMON_TOKEN::EOF_TYPE, \"\");");
	    tabs--;
	    println("end;");
	    println("");
	    return;
	}

	// Create the synthesized nextToken() rule
	RuleBlock nextTokenBlk = MakeGrammar.createNextTokenRule(grammar, gra

⌨️ 快捷键说明

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