htmlcodegenerator.java

来自「SRI international 发布的OAA框架软件」· Java 代码 · 共 781 行 · 第 1/2 页

JAVA
781
字号
		}
		*/
		_print(". ");
	}
/** Generate code for the given grammar element.
 * @param blk The (...)* block to generate
 */
public void gen(ZeroOrMoreBlock blk) {
	genGenericBlock(blk, "*");
}
protected void genAlt(Alternative alt) {
	if (alt.getTreeSpecifier() != null) {
		_print(alt.getTreeSpecifier().getText());
	}
	prevAltElem = null;
	for (AlternativeElement elem = alt.head; !(elem instanceof BlockEndElement); elem = elem.next) {
		elem.generate();
		firstElementInAlt = false;
		prevAltElem = elem;
	}
}
	/** Generate the header for a block, which may be a RuleBlock or a
	 * plain AlternativeBLock.  This generates any variable declarations,
	 * init-actions, and syntactic-predicate-testing variables.
	 * @blk The block for which the preamble is to be generated.
	 */
	protected void genBlockPreamble(AlternativeBlock blk) {
		// dump out init action
		if ( blk.initAction!=null ) {
			printAction("{" + blk.initAction + "}");
		}
	}
/**Generate common code for a block of alternatives; return a postscript
 * that needs to be generated at the end of the block.  Other routines
 * may append else-clauses and such for error checking before the postfix
 * is generated.
 */
public void genCommonBlock(AlternativeBlock blk) {
	for (int i = 0; i < blk.alternatives.size(); i++) {
		Alternative alt = blk.getAlternativeAt(i);
		AlternativeElement elem = alt.head;

		// dump alt operator |
		if ( i>0 && blk.alternatives.size()>1 ) {
			/*
			// only do newline if the last element wasn't a multi-line block
			if ( prevAltElem==null ||
				 !(prevAltElem instanceof AlternativeBlock) ||
				 ((AlternativeBlock)prevAltElem).alternatives.size()==1 )
			{
				_println("");
			}
			*/
			_println("");
			print("|\t");
		}

		// Dump the alternative, starting with predicates
		
		boolean save = firstElementInAlt;
		firstElementInAlt = true;
		tabs++;	// in case we do a newline in alt, increase the tab indent
		// Dump semantic predicates
		if (alt.semPred != null) {
			println("{" + alt.semPred + "}?");
		}
		// Dump syntactic predicate
		if (alt.synPred != null) {
			genSynPred(alt.synPred);
		}
		genAlt(alt);
		tabs--;
		firstElementInAlt = save;
	}
}
	/** Generate a textual representation of the follow set
	 * for a block.
	 * @param blk  The rule block of interest
	 */
	public void genFollowSetForRuleBlock(RuleBlock blk)
	{
		Lookahead follow = grammar.theLLkAnalyzer.FOLLOW(1, blk.endNode);
		printSet(grammar.maxk, 1, follow);
	}
protected void genGenericBlock(AlternativeBlock blk, String blkOp) {
	if (blk.alternatives.size() > 1) {
		// make sure we start on a new line
		if (!firstElementInAlt) {
			// only do newline if the last element wasn't a multi-line block
			if ( prevAltElem==null ||
				 !(prevAltElem instanceof AlternativeBlock) ||
				 ((AlternativeBlock)prevAltElem).alternatives.size()==1 )
			{
				_println("");
				print("(\t");
			}
			else {
				_print("(\t");
			}
			// _println("");
			// print("(\t");
		}
		else {
			_print("(\t");
		}
	} else {
		_print("( ");
	}
	genBlockPreamble(blk);
	genCommonBlock(blk);
	if (blk.alternatives.size() > 1) {
		_println("");
		print(")" + blkOp + " ");
		// if not last element of alt, need newline & to indent
		if ( !(blk.next instanceof BlockEndElement) ) {
			_println("");
			print("");
		}
	} else {
		_print(")" + blkOp + " ");
	}
}
	/** Generate a header that is common to all TXT files */
	protected void genHeader() 
	{
		println("<HTML>");
		println("<HEAD>");
		println("<TITLE>Grammar "+tool.grammarFile+"</TITLE>");
		println("</HEAD>");
		println("<BODY>");
		println("<table border=1 cellpadding=5>");
		println("<tr>");
		println("<td>");
		println("<font size=+2>Grammar "+grammar.getClassName()+"</font><br>");
		println("<a href=http://www.ANTLR.org>ANTLR</a>-generated HTML file from "+tool.grammarFile);
		println("<p>");
		println("Terence Parr, <a href=http://www.magelang.com>MageLang Institute</a>");
		println("<br>ANTLR Version "+Tool.version+"; 1989-1999");
		println("</td>");
		println("</tr>");
		println("</table>");
		println("<PRE>");
		tabs++;
		printAction(behavior.getHeaderAction(""));
		tabs--;
	}
	/**Generate the lookahead set for an alternate. */
	protected void genLookaheadSetForAlt(Alternative alt) {
		if ( doingLexRules && alt.cache[1].containsEpsilon() ) {
			println("MATCHES ALL");
			return;
		}
		int depth = alt.lookaheadDepth;
		if ( depth == GrammarAnalyzer.NONDETERMINISTIC ) {
			// if the decision is nondeterministic, do the best we can: LL(k)
			// any predicates that are around will be generated later.
			depth = grammar.maxk;
		}
		for (int i = 1; i <= depth; i++)
		{
			Lookahead lookahead = alt.cache[i];
			printSet(depth, i, lookahead);
		}
	}
	/** Generate a textual representation of the lookahead set
	 * for a block.
	 * @param blk  The block of interest
	 */
	public void genLookaheadSetForBlock(AlternativeBlock blk)
	{
		// Find the maximal lookahead depth over all alternatives
		int depth = 0;
		for (int i=0; i<blk.alternatives.size(); i++) {
			Alternative alt = blk.getAlternativeAt(i);
			if (alt.lookaheadDepth == GrammarAnalyzer.NONDETERMINISTIC) {
				depth = grammar.maxk;
				break;
			} 
			else if (depth < alt.lookaheadDepth) {
				depth = alt.lookaheadDepth;
			}
		}

		for (int i = 1; i <= depth; i++)
		{
			Lookahead lookahead = grammar.theLLkAnalyzer.look(i, blk);
			printSet(depth, i, lookahead);
		}
	}
	/** Generate the nextToken rule.
	 * nextToken is a synthetic lexer rule that is the implicit OR of all
	 * user-defined lexer rules.
	 */
	public void genNextToken() {
		println("");
		println("/** Lexer nextToken rule:");
		println(" *  The lexer nextToken rule is synthesized from all of the user-defined");
		println(" *  lexer rules.  It logically consists of one big alternative block with");
		println(" *  each user-defined rule being an alternative.");
		println(" */");

		// Create the synthesized rule block for nextToken consisting
		// of an alternate block containing all the user-defined lexer rules.
		RuleBlock blk = MakeGrammar.createNextTokenRule(grammar, grammar.rules, "nextToken");

		// Define the nextToken rule symbol
		RuleSymbol nextTokenRs = new RuleSymbol("mnextToken");
		nextTokenRs.setDefined();
		nextTokenRs.setBlock(blk);
		nextTokenRs.access = "private";
		grammar.define(nextTokenRs);

		/*
		// Analyze the synthesized block
		if (!grammar.theLLkAnalyzer.deterministic(blk))
		{
			println("The grammar analyzer has determined that the synthesized");
			println("nextToken rule is non-deterministic (i.e., it has ambiguities)");
			println("This means that there is some overlap of the character");
			println("lookahead for two or more of your lexer rules.");
		}
		*/

		genCommonBlock(blk);
	}
	/** Generate code for a named rule block
	 * @param s The RuleSymbol describing the rule to generate
	*/
	public void genRule(RuleSymbol s) {
		if ( s==null || !s.isDefined() ) return;	// undefined rule
		println("");
		if ( s.comment!=null ) {
			_println(s.comment);
		}
		if (s.access.length() != 0) {
			if ( !s.access.equals("public") ) {
				_print(s.access+" ");
			}
		}
		_print("<a name="+s.getId()+">");
		_print(s.getId());
		_print("</a>");
		
		// Get rule return type and arguments
		RuleBlock rblk = s.getBlock();

		// Gen method return value(s)
		if (rblk.returnAction != null) {
			_print("["+rblk.returnAction+"]");
		}
		// Gen arguments
		if (rblk.argAction != null) 
		{
			_print(" returns [" + rblk.argAction+"]");
		}
		_println("");
		tabs++;
		print(":\t");

		// Dump any init-action
		// genBlockPreamble(rblk);

		// Dump the alternates of the rule
		genCommonBlock(rblk);

		_println("");
		println(";");
		tabs--;
	}
	/** Generate the syntactic predicate.  This basically generates
	 * the alternative block, buts tracks if we are inside a synPred
	 * @param blk  The syntactic predicate block
	 */
	protected void genSynPred(SynPredBlock blk) {
		syntacticPredLevel++;
		genGenericBlock(blk, " =>");
		syntacticPredLevel--;
	}
	public void genTail() {
		println("</PRE>");
		println("</BODY>");
		println("</HTML>");
	}
	/** Generate the token types TXT file */
	protected void genTokenTypes(TokenManager tm) throws IOException {
		// Open the token output TXT file and set the currentOutput stream
		System.out.println("Generating " + tm.getName() + TokenTypesFileSuffix+TokenTypesFileExt);
		currentOutput = antlr_oaa.Tool.openOutputFile(tm.getName() + TokenTypesFileSuffix+TokenTypesFileExt);
		//SAS: changed for proper text file io
		tabs = 0;
	
		// Generate the header common to all diagnostic files
		genHeader();

		// Generate a string for each token.  This creates a static
		// array of Strings indexed by token type.
		println("");
		println("*** Tokens used by the parser");
		println("This is a list of the token numeric values and the corresponding");
		println("token identifiers.  Some tokens are literals, and because of that");
		println("they have no identifiers.  Literals are double-quoted.");
		tabs++;

		// Enumerate all the valid token types
		Vector v = tm.getVocabulary();
		for (int i = Token.MIN_USER_TYPE; i < v.size(); i++) {
			String s = (String)v.elementAt(i);
			if (s != null) {
				println(s + " = " + i);
			}
		}

		// Close the interface
		tabs--;
		println("*** End of tokens used by the parser");

		// Close the tokens output file
		currentOutput.close();
		currentOutput = null;
	}
	/** Get a string for an expression to generate creation of an AST subtree.
	  * @param v A Vector of String, where each element is an expression in the target language yielding an AST node.
	  */
	public String getASTCreateString(Vector v) {
		return null;
	}
	/** Get a string for an expression to generate creating of an AST node
	  * @param str The arguments to the AST constructor
	  */
	public String getASTCreateString(GrammarAtom atom, String str) {
		return null;
	}
	/** Map an identifier to it's corresponding tree-node variable.
	  * This is context-sensitive, depending on the rule and alternative
	  * being generated
	  * @param id The identifier name to map
	  * @param forInput true if the input tree node variable is to be returned, otherwise the output variable is returned.
	  */
	public String mapTreeId(String id, ActionTransInfo tInfo) {
		return id;
	}
	/** Format a lookahead or follow set.
	 * @param depth The depth of the entire lookahead/follow
	 * @param k The lookahead level to print
	 * @param lookahead  The lookahead/follow set to print
	 */
	public void printSet(int depth, int k, Lookahead lookahead) {
		int numCols = 5;

		int[] elems = lookahead.fset.toArray();

		if (depth != 1) {
			print("k==" + k + ": {");
		} else {
			print("{ ");
		}
		if (elems.length > numCols) {
			_println("");
			tabs++;
			print("");
		}

		int column = 0;
		for (int i = 0; i < elems.length; i++)
		{
			column++;
			if (column > numCols) {
				_println("");
				print("");
				column = 0;
			}
			if (doingLexRules) {
				_print(charFormatter.literalChar(elems[i]));
			} else {
				_print((String)grammar.tokenManager.getVocabulary().elementAt(elems[i]));
			}
			if (i != elems.length-1) {
				_print(", ");
			}
		}

		if (elems.length > numCols) {
			_println("");
			tabs--;
			print("");
		}
		_println(" }");
	}
}

⌨️ 快捷键说明

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