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

📄 sathercodegenerator.java

📁 SRI international 发布的OAA框架软件
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
	// Close the lexer output stream
	currentOutput.close();
	currentOutput = null;
    }
    /** Generate code for the given grammar element.
	 * @param blk The (...)+ block to generate
	 */
    public void gen(OneOrMoreBlock blk) {
	if ( DEBUG_CODE_GENERATOR ) System.out.println("gen+("+blk+")");
	String label;
	String cnt;
	//              println("{"); // cannot nest Sather scopes within a routine
	genBlockPreamble(blk);
	if ( blk.getLabel() != null ) {
	    cnt = getNextSatherPrefix() + "_cnt_"+ blk.getLabel();
	}
	else {
	    cnt = getNextSatherPrefix() + "_cnt" + blk.ID;
	}
	println( cnt + " : INT := 0;");
	//  		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;
	    }

	// generate exit test if greedy set to false
	// and an alt is ambiguous with exit branch
	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 ( " + cnt + " >= 1 and " + predictExit + " ) then break! end; -- if");
	}
	
	JavaBlockFinishingInfo howToFinish = genCommonBlock(blk, false);
	genBlockFinish(
		       howToFinish, 
		       "if ( " + cnt + " >= 1 ) then break! else " + throwNoViable + " end; -- if"
		       );

	println( cnt + " := " + cnt + " + 1;" );
	tabs--;
	println("end; -- loop");
	//		println("}"); // cannot nest Sather scopes within a routine

	// Restore previous AST generation
	currentASTResult = saveCurrentASTResult;
    }
    /** Generate the parser Java file */
    public void gen(ParserGrammar g) throws IOException {

	// if debugging, set up a new vector to keep track of sempred
	//   strings for this grammar
	if (g.debuggingOutput)
	    semPreds = new Vector();

	setGrammar(g);
	if (!(grammar instanceof ParserGrammar)) {
	    tool.panic("Internal error generating parser");
	}

	// Open the output stream for the parser and set the currentOutput
	// SAS: moved file setup so subclass could do it (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 preamble
	println(grammar.preambleAction.getText());

	// Generate parser class definition
	String sup=null;
	if ( grammar.superClass != null )
	    sup = grammar.superClass.toUpperCase();
	else
	    sup = "ANTLR_" + grammar.getSuperClass().toUpperCase();

	// print javadoc comment if any
	if ( grammar.comment!=null ) {
	    _println(grammar.comment);
	}
		
	println("class " + grammar.getClassName() + "{ TOKEN < $ANTLR_TOKEN, AST < $ANTLR_AST{AST} } is");
	tabs++;
	println("include " + sup + "{ TOKEN, " + labeledElementASTType + " } create -> super_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
	  }
	*/

	// set up an array of all the rule names so the debugger can
	// keep track of them only by number -- less to store in tree...
	if (grammar.debuggingOutput) {
	    println("const sa_rule_names : ARRAY{STR} := |");

	    Enumeration 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 user-defined parser class members
	print(
	      processActionForTreeSpecifiers(grammar.classMemberAction.getText(), 0, currentRule, null)
	      );

	// Generate parser class constructor from TokenBuffer
	println("");
	println( "create ( token_buf : ANTLR_TOKEN_BUFFER{TOKEN} , k : INT ) : SAME is");
	tabs++;
	println("res : SAME := super_create( token_buf, k );");
	println("res.token_names := sa_token_names;");
	// println("res.ast_factory := #ANTLR_COMMON_AST_FACTORY;");

	// if debugging, set up arrays and call the user-overridable
	//   debugging setup method
	if ( grammar.debuggingOutput ) {
	    println("res.rule_names  := sa_rule_names;");
	    println("res.sem_pred_names := sa_sem_pred_names;");
	    println("res.setup_debugging( token_buf );");
	}	
	println("return res;");
	tabs--;
	println("end; -- create");
	println("");

	println( "create ( token_buf : ANTLR_TOKEN_BUFFER{TOKEN} ) : SAME is");
	tabs++;
	println("return #SAME( token_buf, " + grammar.maxk + ");");
	tabs--;
	println("end; -- create");
	println("");

	// Generate parser class constructor from TokenStream
	println( "create ( lexer : $ANTLR_TOKEN_STREAM{TOKEN} , k : INT ) : SAME is");
	tabs++;
	println("res : SAME := super_create( lexer, k );");
	println("res.token_names := sa_token_names;");
	// println("res.ast_factory := #ANTLR_COMMON_AST_FACTORY;");

	// if debugging, set up arrays and call the user-overridable
	//   debugging setup method
	if ( grammar.debuggingOutput ) {
	    println("res.rule_names := sa_rule_names;");
	    println("res.sem_pred_names := sa_sem_pred_names;");
	    println("res.setup_debugging( lexer );");
	}
	println("return res;");
	tabs--;
	println("end; -- create");
	println("");

	println( "create( lexer : $ANTLR_TOKEN_STREAM{TOKEN} ) : SAME is");
	tabs++;
	println("res : SAME := #SAME( lexer, " + grammar.maxk + ");");
	println("return res;");
	tabs--;
	println("end; -- create");
	println("");

	println( "create ( state : ANTLR_PARSER_SHARED_INPUT_STATE{TOKEN} ) : SAME is ");
	tabs++;
	println("res : SAME := super_create( state," + grammar.maxk + ");");
	println("res.token_names := sa_token_names;");
	// println("res.ast_factory := #ANTLR_COMMON_AST_FACTORY;");
	println("return res;");
	tabs--;
	println("end; -- create");
	println("");

	// Generate code for each rule in the grammar
	Enumeration ids = grammar.rules.elements();
	int ruleNum=0;
	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());

	// Generate the semantic predicate map for debugging
	if (grammar.debuggingOutput)
	    genSemPredMap();

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

	// Close the parser output stream
	currentOutput.close();
	currentOutput = null;
    }
    /** Generate code for the given grammar element.
	 * @param blk The rule-reference to generate
	 */
    public void gen(RuleRefElement rr) {
	if ( DEBUG_CODE_GENERATOR ) System.out.println("genRR("+rr+")");
	RuleSymbol rs = (RuleSymbol)grammar.getSymbol(rr.targetRule);
	if (rs == null || !rs.isDefined())
	    {
		// Is this redundant???
		tool.error("Rule '" + rr.targetRule + "' is not defined", grammar.getFilename(), rr.getLine());
		return;
	    }
	if (!(rs instanceof RuleSymbol))
	    {
		// Is this redundant???
		tool.error("'" + rr.targetRule + "' does not name a grammar rule", grammar.getFilename(), rr.getLine());
		return;
	    }

	genErrorTryForElement(rr);

	// AST value for labeled rule refs in tree walker.
	// This is not AST construction;  it is just the input tree node value.
	if ( grammar instanceof TreeWalkerGrammar &&
	     rr.getLabel() != null && 
	     syntacticPredLevel == 0 )
	    {
		println("if ( SYS::is_eq( sa_t , " + labeledElementASTType + "::ASTNULL ) ) then");
		tabs++;
		println( rr.getLabel() + " := void;");
		tabs--;
		println("else");
		println(rr.getLabel() + " := " + lt1Value + ";" );
		println("end; -- if");
	    }
		
	// if in lexer and ! on rule ref or alt or rule, save buffer index to kill later
	if ( grammar instanceof LexerGrammar && (!saveText||rr.getAutoGenType()==GrammarElement.AUTO_GEN_BANG) ) {
	    println("sa_save_index := text.length;");
	}
		
	// Process return value assignment if any
	printTabs();
	if (rr.idAssign != null)
	    {
		// Warn if the rule has no return type
		if (rs.block.returnAction == null)
		    {
			tool.warning("Rule '" + rr.targetRule + "' has no return type", grammar.getFilename(), rr.getLine());
		    }
		_print(rr.idAssign + ":=");
	    } else {
		// Warn about return value if any, but not inside syntactic predicate
		if ( !(grammar instanceof LexerGrammar) && syntacticPredLevel == 0 && rs.block.returnAction != null)
		    {
			tool.warning("Rule '" + rr.targetRule + "' returns a value", grammar.getFilename(), rr.getLine());
		    }
	    }

	// Call the rule
	GenRuleInvocation(rr);

	// if in lexer and ! on element or alt or rule, save buffer index to kill later
	if ( grammar instanceof LexerGrammar && (!saveText||rr.getAutoGenType()==GrammarElement.AUTO_GEN_BANG) ) {
	    println("text := text.substring( 0, sa_save_index); -- truncate");
	}

	// if not in a syntactic predicate
	if (syntacticPredLevel == 0) {
	    boolean doNoGuessTest = (
				     grammar.hasSyntacticPredicate &&
				     (
				      grammar.buildAST && rr.getLabel() != null || 
				      (genAST && rr.getAutoGenType() == GrammarElement.AUTO_GEN_NONE)
				      )
				     );
	    if (doNoGuessTest) {
		println("if ( input_state.guessing = 0 ) then"); 
		tabs++;
	    }

	    if (grammar.buildAST && rr.getLabel() != null) {
				// always gen variable for rule return on labeled rules
		println( rr.getLabel() + "_ast := return_ast;");
	    }
	    if (genAST) {
		switch (rr.getAutoGenType()) {
		case GrammarElement.AUTO_GEN_NONE:
		    println("current_ast.add_child( return_ast );");
		    break;
		case GrammarElement.AUTO_GEN_CARET:
		    tool.error("Internal: encountered ^ after rule reference");
		    break;
		default:
		    break;
		}
	    }

	    // if a lexer and labeled, Token label defined at rule level, just set it here
	    if ( grammar instanceof LexerGrammar && rr.getLabel() != null ) {
		println(rr.getLabel()+" := sa_return_token;");
	    }	

	    if (doNoGuessTest) {
		tabs--;
		println("end;"); 
	    }
	}
	genErrorCatchForElement(rr);
    }
    /** Generate code for the given grammar element.
	 * @param blk The string-literal reference to generate
	 */
    public void gen(StringLiteralElement atom) {
	if ( DEBUG_CODE_GENERATOR ) System.out.println("genString("+atom+")");

	// Variable declarations for labeled elements
	if (atom.getLabel()!=null && syntacticPredLevel == 0) {
	    println(atom.getLabel() + " := " + lt1Value + ";");
	}

	// AST
	genElementAST(atom);

	// is there a bang on the literal?
	boolean oldsaveText = saveText;
	saveText = saveText && atom.getAutoGenType()==GrammarElement.AUTO_GEN_NONE;

	// matching
	genMatch(atom);
		
	saveText = oldsaveText;

	// 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 token-range reference to generate
	 */
    public void gen(TokenRangeElement r) {
	genErrorTryForElement(r);
	if ( r.getLabel()!=null  && syntacticPredLevel == 0) {
	    println(r.getLabel() + " := " + lt1Value + ";");

⌨️ 快捷键说明

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