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

📄 grammar.java

📁 ANTLR(ANother Tool for Language Recognition)它是这样的一种工具
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
		if ( r!=null ) {			defineLabel(r, label, element, TOKEN_LIST_LABEL);		}	}	public void defineRuleListLabel(String ruleName,									antlr.Token label,									GrammarAST element)	{		Rule r = getRule(ruleName);		if ( r!=null ) {			if ( !r.getHasMultipleReturnValues() ) {				ErrorManager.grammarError(					ErrorManager.MSG_LIST_LABEL_INVALID_UNLESS_RETVAL_STRUCT,this,					label,label.getText());			}			defineLabel(r, label, element, RULE_LIST_LABEL);		}	}	/** Track a rule reference within an outermost alt of a rule.  Used	 *  at the moment to decide if $ruleref refers to a unique rule ref in	 *  the alt.  Rewrite rules force tracking of all rule AST results.	 *	 *  This data is also used to verify that all rules have been defined.	 */	public void altReferencesRule(String ruleName, GrammarAST refAST, int outerAltNum) {		Rule r = getRule(ruleName);		if ( r==null ) {			return;		}		r.trackRuleReferenceInAlt(refAST, outerAltNum);		antlr.Token refToken = refAST.getToken();		if ( !ruleRefs.contains(refToken) ) {			ruleRefs.add(refToken);		}	}	/** Track a token reference within an outermost alt of a rule.  Used	 *  to decide if $tokenref refers to a unique token ref in	 *  the alt. Does not track literals!	 *	 *  Rewrite rules force tracking of all tokens.	 */	public void altReferencesTokenID(String ruleName, GrammarAST refAST, int outerAltNum) {		Rule r = getRule(ruleName);		if ( r==null ) {			return;		}		r.trackTokenReferenceInAlt(refAST, outerAltNum);		if ( !tokenIDRefs.contains(refAST.getToken()) ) {			tokenIDRefs.add(refAST.getToken());		}	}	/** To yield smaller, more readable code, track which rules have their	 *  predefined attributes accessed.  If the rule has no user-defined	 *  return values, then don't generate the return value scope classes	 *  etc...  Make the rule have void return value.  Don't track for lexer	 *  rules.	 */	public void referenceRuleLabelPredefinedAttribute(String ruleName) {		Rule r = getRule(ruleName);		if ( r!=null && type!=LEXER ) {			// indicate that an action ref'd an attr unless it's in a lexer			// so that $ID.text refs don't force lexer rules to define			// return values...Token objects are created by the caller instead.			r.referencedPredefinedRuleAttributes = true;		}	}	public void checkRuleReference(GrammarAST refAST,								   GrammarAST argsAST,								   String currentRuleName)	{		Rule r = getRule(refAST.getText());		if ( refAST.getType()==ANTLRParser.RULE_REF ) {			if ( argsAST!=null ) {				// rule[args]; ref has args                if ( r!=null && r.argActionAST==null ) {					// but rule def has no args					ErrorManager.grammarError(						ErrorManager.MSG_RULE_HAS_NO_ARGS,						this,						argsAST.getToken(),						r.name);				}			}			else {				// rule ref has no args				if ( r!=null && r.argActionAST!=null ) {					// but rule def has args					ErrorManager.grammarError(						ErrorManager.MSG_MISSING_RULE_ARGS,						this,						refAST.getToken(),						r.name);				}			}		}		else if ( refAST.getType()==ANTLRParser.TOKEN_REF ) {			if ( type!=LEXER ) {				if ( argsAST!=null ) {					// args on a token ref not in a lexer rule					ErrorManager.grammarError(						ErrorManager.MSG_ARGS_ON_TOKEN_REF,						this,						refAST.getToken(),						refAST.getText());				}				return; // ignore token refs in nonlexers			}			if ( argsAST!=null ) {				// tokenRef[args]; ref has args				if ( r!=null && r.argActionAST==null ) {					// but token rule def has no args					ErrorManager.grammarError(						ErrorManager.MSG_RULE_HAS_NO_ARGS,						this,						argsAST.getToken(),						r.name);				}			}			else {				// token ref has no args				if ( r!=null && r.argActionAST!=null ) {					// but token rule def has args					ErrorManager.grammarError(						ErrorManager.MSG_MISSING_RULE_ARGS,						this,						refAST.getToken(),						r.name);				}			}		}	}	/** Return a list of left-recursive rules; no analysis can be done	 *  successfully on these.  Useful to skip these rules then and also	 *  for ANTLRWorks to highlight them.	 */	public Set getLeftRecursiveRules() {		if ( nfa==null ) {			createNFAs();		}		if ( leftRecursiveRules!=null ) {			return leftRecursiveRules;		}		checkAllRulesForLeftRecursion();		return leftRecursiveRules;	}	/** Check all rules for infinite left recursion before analysis. Return list	 *  of troublesome rule cycles.  This method has two side-effects: it notifies	 *  the error manager that we have problems and it sets the list of	 *  recursive rules that we should ignore during analysis.	 *	 *  Return type: List<Set<String(rule-name)>>.	 */	public List checkAllRulesForLeftRecursion() {		createNFAs(); // make sure we have NFAs		leftRecursiveRules = new HashSet();		List listOfRecursiveCycles = new ArrayList(); // List<Set<String(rule-name)>>		for (int i = 0; i < ruleIndexToRuleList.size(); i++) {			String ruleName = (String)ruleIndexToRuleList.elementAt(i);			if ( ruleName!=null ) {				NFAState s = getRuleStartState(ruleName);				visitedDuringRecursionCheck = new HashSet();				visitedDuringRecursionCheck.add(ruleName);				Set visitedStates = new HashSet();				traceStatesLookingForLeftRecursion(s, visitedStates, listOfRecursiveCycles);			}		}		if ( listOfRecursiveCycles.size()>0 ) {			ErrorManager.leftRecursionCycles(listOfRecursiveCycles);		}		return listOfRecursiveCycles;	}	/** From state s, look for any transition to a rule that is currently	 *  being traced.  When tracing r, visitedDuringRecursionCheck has r	 *  initially.  If you reach an accept state, return but notify the	 *  invoking rule that it is nullable, which implies that invoking	 *  rule must look at follow transition for that invoking state.	 *  The visitedStates tracks visited states within a single rule so	 *  we can avoid epsilon-loop-induced infinite recursion here.  Keep	 *  filling the cycles in listOfRecursiveCycles and also, as a	 *  side-effect, set leftRecursiveRules.	 */	protected boolean traceStatesLookingForLeftRecursion(NFAState s,														 Set visitedStates,														 List listOfRecursiveCycles)	{		if ( s.isAcceptState() ) {			// this rule must be nullable!			// At least one epsilon edge reached accept state			return true;		}		if ( visitedStates.contains(s) ) {			// within same rule, we've hit same state; quit looping			return false;		}		visitedStates.add(s);		boolean stateReachesAcceptState = false;		Transition t0 = s.transition(0);		if ( t0 instanceof RuleClosureTransition ) {			String targetRuleName = ((NFAState)t0.target).getEnclosingRule();			if ( visitedDuringRecursionCheck.contains(targetRuleName) ) {				// record left-recursive rule, but don't go back in				leftRecursiveRules.add(targetRuleName);				/*				System.out.println("already visited "+targetRuleName+", calling from "+								   s.getEnclosingRule());				*/				addRulesToCycle(targetRuleName,								s.getEnclosingRule(),								listOfRecursiveCycles);			}			else {				// must visit if not already visited; send new visitedStates set				visitedDuringRecursionCheck.add(targetRuleName);				boolean callReachedAcceptState =					traceStatesLookingForLeftRecursion((NFAState)t0.target,													   new HashSet(),													   listOfRecursiveCycles);				// we're back from visiting that rule				visitedDuringRecursionCheck.remove(targetRuleName);				// must keep going in this rule then				if ( callReachedAcceptState ) {					NFAState followingState =						((RuleClosureTransition)t0).getFollowState();					stateReachesAcceptState |=						traceStatesLookingForLeftRecursion(followingState,														   visitedStates,														   listOfRecursiveCycles);				}			}		}		else if ( t0.label.isEpsilon() ) {			stateReachesAcceptState |=				traceStatesLookingForLeftRecursion((NFAState)t0.target, visitedStates, listOfRecursiveCycles);		}		// else it has a labeled edge		// now do the other transition if it exists		Transition t1 = s.transition(1);		if ( t1!=null ) {			stateReachesAcceptState |=				traceStatesLookingForLeftRecursion((NFAState)t1.target,												   visitedStates,												   listOfRecursiveCycles);		}		return stateReachesAcceptState;	}	/** enclosingRuleName calls targetRuleName, find the cycle containing	 *  the target and add the caller.  Find the cycle containing the caller	 *  and add the target.  If no cycles contain either, then create a new	 *  cycle.  listOfRecursiveCycles is List<Set<String>> that holds a list	 *  of cycles (sets of rule names).	 */	protected void addRulesToCycle(String targetRuleName,								   String enclosingRuleName,								   List listOfRecursiveCycles)	{		boolean foundCycle = false;		for (int i = 0; i < listOfRecursiveCycles.size(); i++) {			Set rulesInCycle = (Set)listOfRecursiveCycles.get(i);			// ensure both rules are in same cycle			if ( rulesInCycle.contains(targetRuleName) ) {				rulesInCycle.add(enclosingRuleName);				foundCycle = true;			}			if ( rulesInCycle.contains(enclosingRuleName) ) {				rulesInCycle.add(targetRuleName);				foundCycle = true;			}		}		if ( !foundCycle ) {			Set cycle = new HashSet();			cycle.add(targetRuleName);			cycle.add(enclosingRuleName);			listOfRecursiveCycles.add(cycle);		}	}	/** Rules like "a : ;" and "a : {...} ;" should not generate	 *  try/catch blocks for RecognitionException.  To detect this	 *  it's probably ok to just look for any reference to an atom	 *  that can match some input.  W/o that, the rule is unlikey to have	 *  any else.	 */	public boolean isEmptyRule(GrammarAST block) {		GrammarAST aTokenRefNode =			block.findFirstType(ANTLRParser.TOKEN_REF);		GrammarAST aStringLiteralRefNode =			block.findFirstType(ANTLRParser.STRING_LITERAL);		GrammarAST aCharLiteralRefNode =			block.findFirstType(ANTLRParser.CHAR_LITERAL);		GrammarAST aWildcardRefNode =			block.findFirstType(ANTLRParser.WILDCARD);		GrammarAST aRuleRefNode =			block.findFirstType(ANTLRParser.RULE_REF);		if ( aTokenRefNode==null&&			aStringLiteralRefNode==null&&			aCharLiteralRefNode==null&&			aWildcardRefNode==null&&			aRuleRefNode==null )		{			return true;		}		return false;	}    public int getTokenType(String tokenName) {        Integer I = null;        if ( tokenName.charAt(0)=='\'') {            I = (Integer)stringLiteralToTypeMap.get(tokenName);        }        else { // must be a label like ID            I = (Integer)tokenIDToTypeMap.get(tokenName);        }        int i = (I!=null)?I.intValue():Label.INVALID;		//System.out.println("grammar type "+type+" "+tokenName+"->"+i);        return i;    }	/** Get the list of tokens that are IDs like BLOCK and LPAREN */	public Set getTokenIDs() {		return tokenIDToTypeMap.keySet();	}	/** Return an ordered integer list of token types that have no	 *  corresponding token ID like INT or KEYWORD_BEGIN; for stuff	 *  like 'begin'.	 */	public Collection getTokenTypesWithoutID() {		List types = new ArrayList();		for (int t =Label.MIN_TOKEN_TYPE; t<=getMaxTokenType(); t++) {			String name = getTokenDisplayName(t);			if ( name.charAt(0)=='\'' ) {				types.add(Utils.integer(t));			}		}		return types;	}	/** Get a list of all token IDs and literals that have an associated	 *  token type.	 */	public Set getTokenDisplayNames() {		Set names = new HashSet();		for (int t =Label.MIN_TOKEN_TYPE; t <=getMaxTokenType(); t++) {			names.add(getTokenDisplayName(t));		}		return names;	}	/** Given a literal like (the 3 char sequence with single quotes) 'a',	 *  return the int value of 'a'. Convert escape sequences here also.	 *  ANTLR's antlr.g parser does not convert escape sequences.	 *	 *  11/26/2005: I changed literals to always be '...' even for strings.	 *  This routine still works though.     */    public static int getCharValueFromGrammarCharLiteral(String literal) {        if ( literal.length()==3 ) {			// 'x'            return literal.charAt(1); // no escape char        }        else if ( literal.length() == 4 )        {			// '\x'  (antlr lexer will catch invalid char)			int escChar = literal.charAt(2);			int charVal = ANTLRLiteralEscapedCharValue[escChar];			if ( charVal==0 ) {				// Unnecessary escapes like '\{' should just yield {				return escChar;			}			return charVal;        }        else if( literal.length() == 8 )        {        	// '\u1234'        	String unicodeChars = literal.substring(3,literal.length()-1);    		return Integer.parseInt(unicodeChars, 16);         }		ErrorManager.assertTrue(false, "invalid char literal: "+literal);		return -1;    }	/** ANTLR does not convert escape sequences during the parse phase because	 *  it could not know how to print String/char literals back out when	 *  printing grammars etc...  Someone in China might use the real unicode	 *  char in a literal as it will display on their screen; when printing	 *  back out, I could not know whether to display or use a unicode escape.	 *	 *  This routine converts a string literal with possible escape sequences

⌨️ 快捷键说明

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