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

📄 codegenerator.java

📁 antlr最新版本V3源代码
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
		outputFileST.setAttribute("generatedTimestamp", Tool.getCurrentTimeStamp());		headerFileST.setAttribute("generatedTimestamp", Tool.getCurrentTimeStamp());		// GENERATE RECOGNIZER		// Walk the AST holding the input grammar, this time generating code		// Decisions are generated by using the precomputed DFAs		// Fill in the various templates with data		CodeGenTreeWalker gen = new CodeGenTreeWalker();		try {			gen.grammar((AST)grammar.getGrammarTree(),						grammar,						recognizerST,						outputFileST,						headerFileST);		}		catch (RecognitionException re) {			ErrorManager.error(ErrorManager.MSG_BAD_AST_STRUCTURE,							   re);		}		genTokenTypeConstants(recognizerST);		genTokenTypeConstants(outputFileST);		genTokenTypeConstants(headerFileST);		if ( grammar.type!=Grammar.LEXER ) {			genTokenTypeNames(recognizerST);			genTokenTypeNames(outputFileST);			genTokenTypeNames(headerFileST);		}		// Now that we know what synpreds are used, we can set into template		Set synpredNames = null;		if ( grammar.synPredNamesUsedInDFA.size()>0 ) {			synpredNames = grammar.synPredNamesUsedInDFA;		}		outputFileST.setAttribute("synpreds", synpredNames);		headerFileST.setAttribute("synpreds", synpredNames);				// all recognizers can see Grammar object		recognizerST.setAttribute("grammar", grammar);		// WRITE FILES		try {			target.genRecognizerFile(tool,this,grammar,outputFileST);			if ( templates.isDefined("headerFile") ) {				StringTemplate extST = templates.getInstanceOf("headerFileExtension");				target.genRecognizerHeaderFile(tool,this,grammar,headerFileST,extST.toString());			}			// write out the vocab interchange file; used by antlr,			// does not change per target			StringTemplate tokenVocabSerialization = genTokenVocabOutput();			String vocabFileName = getVocabFileName();			if ( vocabFileName!=null ) {				write(tokenVocabSerialization, vocabFileName);			}			//System.out.println(outputFileST.getDOTForDependencyGraph(false));		}		catch (IOException ioe) {			ErrorManager.error(ErrorManager.MSG_CANNOT_WRITE_FILE,							   getVocabFileName(),							   ioe);		}		/*		System.out.println("num obj.prop refs: "+ ASTExpr.totalObjPropRefs);		System.out.println("num reflection lookups: "+ ASTExpr.totalReflectionLookups);		*/		return outputFileST;	}	/** Some targets will have some extra scopes like C++ may have	 *  '@headerfile:name {action}' or something.  Make sure the	 *  target likes the scopes in action table.	 */	protected void verifyActionScopesOkForTarget(Map actions) {		Set actionScopeKeySet = actions.keySet();		for (Iterator it = actionScopeKeySet.iterator(); it.hasNext();) {			String scope = (String)it.next();			if ( !target.isValidActionScope(grammar.type, scope) ) {				// get any action from the scope to get error location				Map scopeActions = (Map)actions.get(scope);				GrammarAST actionAST =					(GrammarAST)scopeActions.values().iterator().next();				ErrorManager.grammarError(					ErrorManager.MSG_INVALID_ACTION_SCOPE,grammar,					actionAST.getToken(),scope,					Grammar.grammarTypeToString[grammar.type]);			}		}	}	/** Actions may reference $x::y attributes, call translateAction on	 *  each action and replace that action in the Map.	 */	protected void translateActionAttributeReferences(Map actions) {		Set actionScopeKeySet = actions.keySet();		for (Iterator it = actionScopeKeySet.iterator(); it.hasNext();) {			String scope = (String)it.next();			Map scopeActions = (Map)actions.get(scope);			translateActionAttributeReferencesForSingleScope(null,scopeActions);		}	}	/** Use for translating rule @init{...} actions that have no scope */	protected void translateActionAttributeReferencesForSingleScope(		Rule r,		Map scopeActions)	{		String ruleName=null;		if ( r!=null ) {			ruleName = r.name;		}		Set actionNameSet = scopeActions.keySet();		for (Iterator nameIT = actionNameSet.iterator(); nameIT.hasNext();) {			String name = (String) nameIT.next();			GrammarAST actionAST = (GrammarAST)scopeActions.get(name);			List chunks = translateAction(ruleName,actionAST);			scopeActions.put(name, chunks); // replace with translation		}	}	/** Error recovery in ANTLR recognizers.	 *	 *  Based upon original ideas:	 *	 *  Algorithms + Data Structures = Programs by Niklaus Wirth	 *	 *  and	 *	 *  A note on error recovery in recursive descent parsers:	 *  http://portal.acm.org/citation.cfm?id=947902.947905	 *	 *  Later, Josef Grosch had some good ideas:	 *  Efficient and Comfortable Error Recovery in Recursive Descent Parsers:	 *  ftp://www.cocolab.com/products/cocktail/doca4.ps/ell.ps.zip	 *	 *  Like Grosch I implemented local FOLLOW sets that are combined at run-time	 *  upon error to avoid parsing overhead.	 */	public void generateLocalFOLLOW(GrammarAST referencedElementNode,									String referencedElementName,									String enclosingRuleName,									int elementIndex)	{		NFAState followingNFAState = referencedElementNode.followingNFAState;/*		System.out.print("compute FOLLOW "+referencedElementNode.toString()+						 " for "+referencedElementName+"#"+elementIndex +" in "+						 enclosingRuleName+						 " line="+referencedElementNode.getLine());*/		LookaheadSet follow = null;		if ( followingNFAState!=null ) {			follow = grammar.LOOK(followingNFAState);		}		if ( follow==null ) {			ErrorManager.internalError("no follow state or cannot compute follow");			follow = new LookaheadSet();		}		//System.out.println(" "+follow);        List tokenTypeList = null;        long[] words = null;		if ( follow.tokenTypeSet==null ) {			words = new long[1];            tokenTypeList = new ArrayList();        }		else {			BitSet bits = BitSet.of(follow.tokenTypeSet);			words = bits.toPackedArray();            tokenTypeList = follow.tokenTypeSet.toList();        }		// use the target to convert to hex strings (typically)		String[] wordStrings = new String[words.length];		for (int j = 0; j < words.length; j++) {			long w = words[j];			wordStrings[j] = target.getTarget64BitStringFromValue(w);		}        recognizerST.setAttribute("bitsets.{name,inName,bits,tokenTypes,tokenIndex}",                referencedElementName,                enclosingRuleName,                wordStrings,                tokenTypeList,                Utils.integer(elementIndex));        outputFileST.setAttribute("bitsets.{name,inName,bits,tokenTypes,tokenIndex}",                referencedElementName,                enclosingRuleName,                wordStrings,                tokenTypeList,                Utils.integer(elementIndex));        headerFileST.setAttribute("bitsets.{name,inName,bits,tokenTypes,tokenIndex}",                referencedElementName,                enclosingRuleName,                wordStrings,                tokenTypeList,                Utils.integer(elementIndex));	}	// L O O K A H E A D  D E C I S I O N  G E N E R A T I O N	/** Generate code that computes the predicted alt given a DFA.  The	 *  recognizerST can be either the main generated recognizerTemplate	 *  for storage in the main parser file or a separate file.  It's up to	 *  the code that ultimately invokes the codegen.g grammar rule.	 *	 *  Regardless, the output file and header file get a copy of the DFAs.	 */	public StringTemplate genLookaheadDecision(StringTemplate recognizerST,											   DFA dfa)	{		StringTemplate decisionST;		// If we are doing inline DFA and this one is acyclic and LL(*)		// I have to check for is-non-LL(*) because if non-LL(*) the cyclic		// check is not done by DFA.verify(); that is, verify() avoids		// doesStateReachAcceptState() if non-LL(*)		if ( dfa.canInlineDecision() ) {			decisionST =				acyclicDFAGenerator.genFixedLookaheadDecision(getTemplates(), dfa);		}		else {			// generate any kind of DFA here (cyclic or acyclic)			dfa.createStateTables(this);			outputFileST.setAttribute("cyclicDFAs", dfa);			headerFileST.setAttribute("cyclicDFAs", dfa);			decisionST = templates.getInstanceOf("dfaDecision");			String description = dfa.getNFADecisionStartState().getDescription();			description = target.getTargetStringLiteralFromString(description);			if ( description!=null ) {				decisionST.setAttribute("description", description);			}			decisionST.setAttribute("decisionNumber",									Utils.integer(dfa.getDecisionNumber()));		}		return decisionST;	}	/** A special state is huge (too big for state tables) or has a predicated	 *  edge.  Generate a simple if-then-else.  Cannot be an accept state as	 *  they have no emanating edges.  Don't worry about switch vs if-then-else	 *  because if you get here, the state is super complicated and needs an	 *  if-then-else.  This is used by the new DFA scheme created June 2006.	 */	public StringTemplate generateSpecialState(DFAState s) {		StringTemplate stateST;		stateST = templates.getInstanceOf("cyclicDFAState");		stateST.setAttribute("needErrorClause", Boolean.valueOf(true));		stateST.setAttribute("semPredState",							 Boolean.valueOf(s.isResolvedWithPredicates()));		stateST.setAttribute("stateNumber", s.stateNumber);		stateST.setAttribute("decisionNumber", s.dfa.decisionNumber);		boolean foundGatedPred = false;		StringTemplate eotST = null;		for (int i = 0; i < s.getNumberOfTransitions(); i++) {			Transition edge = (Transition) s.transition(i);			StringTemplate edgeST;			if ( edge.label.getAtom()==Label.EOT ) {				// this is the default clause; has to held until last				edgeST = templates.getInstanceOf("eotDFAEdge");				stateST.removeAttribute("needErrorClause");				eotST = edgeST;			}			else {				edgeST = templates.getInstanceOf("cyclicDFAEdge");				StringTemplate exprST =					genLabelExpr(templates,edge,1);				edgeST.setAttribute("labelExpr", exprST);			}			edgeST.setAttribute("edgeNumber", Utils.integer(i+1));			edgeST.setAttribute("targetStateNumber",								 Utils.integer(edge.target.stateNumber));			// stick in any gated predicates for any edge if not already a pred			if ( !edge.label.isSemanticPredicate() ) {				DFAState t = (DFAState)edge.target;				SemanticContext preds =	t.getGatedPredicatesInNFAConfigurations();				if ( preds!=null ) {					foundGatedPred = true;					StringTemplate predST = preds.genExpr(this,														  getTemplates(),														  t.dfa);					edgeST.setAttribute("predicates", predST.toString());				}			}			if ( edge.label.getAtom()!=Label.EOT ) {				stateST.setAttribute("edges", edgeST);			}		}		if ( foundGatedPred ) {			// state has >= 1 edge with a gated pred (syn or sem)			// must rewind input first, set flag.			stateST.setAttribute("semPredState", new Boolean(foundGatedPred));		}		if ( eotST!=null ) {			stateST.setAttribute("edges", eotST);		}		return stateST;	}	/** Generate an expression for traversing an edge. */	protected StringTemplate genLabelExpr(StringTemplateGroup templates,										  Transition edge,										  int k)	{		Label label = edge.label;		if ( label.isSemanticPredicate() ) {			return genSemanticPredicateExpr(templates, edge);		}		if ( label.isSet() ) {			return genSetExpr(templates, label.getSet(), k, true);		}		// must be simple label		StringTemplate eST = templates.getInstanceOf("lookaheadTest");		eST.setAttribute("atom", getTokenTypeAsTargetLabel(label.getAtom()));		eST.setAttribute("atomAsInt", Utils.integer(label.getAtom()));		eST.setAttribute("k", Utils.integer(k));		return eST;	}	protected StringTemplate genSemanticPredicateExpr(StringTemplateGroup templates,													  Transition edge)	{		DFA dfa = ((DFAState)edge.target).dfa; // which DFA are we in		Label label = edge.label;		SemanticContext semCtx = label.getSemanticContext();		return semCtx.genExpr(this,templates,dfa);	}	/** For intervals such as [3..3, 30..35], generate an expression that	 *  tests the lookahead similar to LA(1)==3 || (LA(1)>=30&&LA(1)<=35)	 */	public StringTemplate genSetExpr(StringTemplateGroup templates,									 IntSet set,									 int k,									 boolean partOfDFA)	{		if ( !(set instanceof IntervalSet) ) {			throw new IllegalArgumentException("unable to generate expressions for non IntervalSet objects");		}		IntervalSet iset = (IntervalSet)set;		if ( iset.getIntervals()==null || iset.getIntervals().size()==0 ) {			StringTemplate emptyST = new StringTemplate(templates, "");			emptyST.setName("empty-set-expr");			return emptyST;		}		String testSTName = "lookaheadTest";		String testRangeSTName = "lookaheadRangeTest";		if ( !partOfDFA ) {			testSTName = "isolatedLookaheadTest";			testRangeSTName = "isolatedLookaheadRangeTest";		}		StringTemplate setST = templates.getInstanceOf("setTest");		Iterator iter = iset.getIntervals().iterator();		int rangeNumber = 1;		while (iter.hasNext()) {			Interval I = (Interval) iter.next();			int a = I.a;			int b = I.b;			StringTemplate eST;			if ( a==b ) {				eST = templates.getInstanceOf(testSTName);				eST.setAttribute("atom", getTokenTypeAsTargetLabel(a));				eST.setAttribute("atomAsInt", Utils.integer(a));				//eST.setAttribute("k",Utils.integer(k));			}			else {				eST = templates.getInstanceOf(testRangeSTName);				eST.setAttribute("lower",getTokenTypeAsTargetLabel(a));				eST.setAttribute("lowerAsInt", Utils.integer(a));				eST.setAttribute("upper",getTokenTypeAsTargetLabel(b));				eST.setAttribute("upperAsInt", Utils.integer(b));				eST.setAttribute("rangeNumber",Utils.integer(rangeNumber));			}			eST.setAttribute("k",Utils.integer(k));			setST.setAttribute("ranges", eST);			rangeNumber++;		}		return setST;	}	// T O K E N  D E F I N I T I O N  G E N E R A T I O N	/** Set attributes tokens and literals attributes in the incoming	 *  code template.  This is not the token vocab interchange file, but	 *  rather a list of token type ID needed by the recognizer.	 */	protected void genTokenTypeConstants(StringTemplate code) {		// make constants for the token types		Iterator tokenIDs = grammar.getTokenIDs().iterator();		while (tokenIDs.hasNext()) {			String tokenID = (String) tokenIDs.next();			int tokenType = grammar.getTokenType(tokenID);			if ( tokenType==Label.EOF ||				 tokenType>=Label.MIN_TOKEN_TYPE )			{				// don't do FAUX labels 'cept EOF				code.setAttribute("tokens.{name,type}", tokenID, Utils.integer(tokenType));

⌨️ 快捷键说明

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