makegrammar.java

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

JAVA
750
字号
		// and switch the list of alternatives.  Adjust the stack of blocks.
		// copy any init action also.
		OneOrMoreBlock b = new OneOrMoreBlock(grammar);
		setBlock(b,context().block);
		BlockContext old = (BlockContext)blocks.pop(); // remove old scope; we want new type of subrule
		blocks.push(new BlockContext());
		context().block = b;
		context().blockEnd = old.blockEnd;
		context().blockEnd.block = b;
	}
	public void optionalSubRule() {
		if (context().block.not) {
			tool.error("'~' cannot be applied to (...)? subrule", grammar.getFilename(), context().block.getLine());
		}
		// convert (X)? -> (X|) so that we can ignore optional blocks altogether!
		// It already thinks that we have a simple subrule, just add option block.
		beginAlt(false);
		endAlt();
	}
	public void refAction(Token action) {
		super.refAction(action);
		context().block.hasAnAction = true;
		addElementToCurrentAlt(new ActionElement(grammar,action));
	}

    public void setUserExceptions(String thr) {
	((RuleBlock)context().block).throwsSpec = thr;
    }

	// Only called for rule blocks
	public void refArgAction(Token action) {
		((RuleBlock)context().block).argAction = action.getText();
	}
	public void refCharLiteral(Token lit, Token label, boolean inverted, int autoGenType, boolean lastInRule) {
		if (!(grammar instanceof LexerGrammar)) {
			tool.error("Character literal only valid in lexer", grammar.getFilename(), lit.getLine());
			return;
		}
		super.refCharLiteral(lit, label, inverted, autoGenType, lastInRule);
		CharLiteralElement cl = new CharLiteralElement((LexerGrammar)grammar, lit, inverted, autoGenType);

		// Generate a warning for non-lowercase ASCII when case-insensitive
		if (
			!((LexerGrammar)grammar).caseSensitive && cl.getType() < 128 && 
			Character.toLowerCase((char)cl.getType()) != (char)cl.getType()
		) {
			tool.warning("Character literal must be lowercase when caseSensitive=false", grammar.getFilename(), lit.getLine());
		}

		addElementToCurrentAlt(cl);
		labelElement(cl, label);

		// if ignore option is set, must add an optional call to the specified rule.
		String ignore = ruleBlock.getIgnoreRule();
		if ( !lastInRule && ignore!=null ) {
			addElementToCurrentAlt(createOptionalRuleRef(ignore, lit.getLine()));
		}
	}
	public void refCharRange(Token t1, Token t2, Token label, int autoGenType, boolean lastInRule) {
		if (!(grammar instanceof LexerGrammar)) {
			tool.error("Character range only valid in lexer", grammar.getFilename(), t1.getLine());
			return;
		}
		int rangeMin = ANTLRLexer.tokenTypeForCharLiteral(t1.getText());
		int rangeMax = ANTLRLexer.tokenTypeForCharLiteral(t2.getText());
		if (rangeMax < rangeMin) {
			tool.error("Malformed range.", grammar.getFilename(), t1.getLine());
			return;
		}

		// Generate a warning for non-lowercase ASCII when case-insensitive
		if (!((LexerGrammar)grammar).caseSensitive) {
			if (rangeMin < 128 && Character.toLowerCase((char)rangeMin) != (char)rangeMin) {
				tool.warning("Character literal must be lowercase when caseSensitive=false", grammar.getFilename(), t1.getLine());
			}
			if (rangeMax < 128 && Character.toLowerCase((char)rangeMax) != (char)rangeMax) {
				tool.warning("Character literal must be lowercase when caseSensitive=false", grammar.getFilename(), t2.getLine());
			}
		}

		super.refCharRange(t1, t2, label, autoGenType, lastInRule);
		CharRangeElement cr = new CharRangeElement((LexerGrammar)grammar, t1, t2, autoGenType);
		addElementToCurrentAlt(cr);
		labelElement(cr, label);

		// if ignore option is set, must add an optional call to the specified rule.
		String ignore = ruleBlock.getIgnoreRule();
		if ( !lastInRule && ignore!=null ) {
			addElementToCurrentAlt(createOptionalRuleRef(ignore, t1.getLine()));
		}
	}

	public void refTokensSpecElementOption(Token tok,
										   Token option,
										   Token value) {
		/*
		System.out.println("setting tokens spec option for "+tok.getText());
		System.out.println(option.getText()+","+value.getText());
		*/
		TokenSymbol ts = (TokenSymbol)
			grammar.tokenManager.getTokenSymbol(tok.getText());
		if ( ts==null ) {
			tool.panic("cannot find "+tok.getText()+"in tokens {...}");
		}
		if ( option.getText().equals("AST") ) {
			ts.setASTNodeType(value.getText());
		}
		else {
			grammar.tool.error("invalid tokens {...} element option:"+
							   option.getText(),
							   grammar.getFilename(),
							   option.getLine());
		}
	}

	public void refElementOption(Token option, Token value) {
		/*
		System.out.println("setting option for "+context().currentElement());
		System.out.println(option.getText()+","+value.getText());
		*/
		AlternativeElement e = context().currentElement();
		if ( e instanceof StringLiteralElement ||
		     e instanceof TokenRefElement ||
		     e instanceof WildcardElement )
	    {
			((GrammarAtom)e).setOption(option, value);
		}
		else {
			tool.error("cannot use element option ("+option.getText()+
					   ") for this kind of element",
					   grammar.getFilename(), option.getLine());
		}
	}

	/** Add an exception handler to an exception spec */
	public void refExceptionHandler(Token exTypeAndName, Token action) {
		super.refExceptionHandler(exTypeAndName, action);
		if (currentExceptionSpec == null)
		{
			tool.panic("exception handler processing internal error");
		}
		currentExceptionSpec.addHandler(new ExceptionHandler(exTypeAndName, action));
	}

	public void refInitAction(Token action) {
		super.refAction(action);
		context().block.setInitAction(action.getText());
	}

	public void refMemberAction(Token act) {
		grammar.classMemberAction = act;
	}

	public void refPreambleAction(Token act) {
		super.refPreambleAction(act);
	}

	// Only called for rule blocks
	public void refReturnAction(Token returnAction) {
		if (grammar instanceof LexerGrammar) {
			String name = CodeGenerator.lexerRuleName(((RuleBlock)context().block).getRuleName());
			RuleSymbol rs = (RuleSymbol)grammar.getSymbol(name);
			if (rs.access.equals("public")) {
				tool.warning("public Lexical rules cannot specify return type", grammar.getFilename(), returnAction.getLine());
				return;
			}
		}
		((RuleBlock)context().block).returnAction = returnAction.getText();
	}

	public void refRule(Token idAssign,
						Token r,
						Token label,
						Token args,
						int autoGenType)
	{
		// Disallow parser rule references in the lexer
		if (grammar instanceof LexerGrammar) {
			//			if (!Character.isUpperCase(r.getText().charAt(0))) {
 			if ( r.type != ANTLRTokenTypes.TOKEN_REF ) {
				tool.error("Parser rule " + r.getText() + " referenced in lexer");
				return;
			}
			if (autoGenType == GrammarElement.AUTO_GEN_CARET) {
				tool.error("AST specification ^ not allowed in lexer", grammar.getFilename(), r.getLine());
			}
		}

		super.refRule(idAssign, r, label, args, autoGenType);
		lastRuleRef = new RuleRefElement(grammar, r, autoGenType);
		if (args != null)
		{
			lastRuleRef.setArgs(args.getText());
		}
		if (idAssign != null)
		{
			lastRuleRef.setIdAssign(idAssign.getText());
		}
		addElementToCurrentAlt(lastRuleRef);

		String id = r.getText();
		//		if ( Character.isUpperCase(id.charAt(0)) ) { // lexer rule?
 		if ( r.type == ANTLRTokenTypes.TOKEN_REF ) { // lexer rule?
			id = CodeGenerator.lexerRuleName(id);
		}
		// update symbol table so it knows what nodes reference the rule.
		RuleSymbol rs = (RuleSymbol)grammar.getSymbol(id);
		rs.addReference(lastRuleRef);
		labelElement(lastRuleRef, label);
	}

	public void refSemPred(Token pred) {
		//System.out.println("refSemPred "+pred.getText());
		super.refSemPred(pred);
		//System.out.println("context().block: "+context().block);
		if ( context().currentAlt().atStart() ) {
			context().currentAlt().semPred = pred.getText();
		}
		else {
			ActionElement a = new ActionElement(grammar,pred);
			a.isSemPred = true;
			addElementToCurrentAlt(a);
		}
		//System.out.println("DONE refSemPred "+pred.getText());
	}
	public void refStringLiteral(Token lit, Token label, int autoGenType, boolean lastInRule) {
		super.refStringLiteral(lit, label, autoGenType, lastInRule);
		if (grammar instanceof TreeWalkerGrammar && autoGenType == GrammarElement.AUTO_GEN_CARET) {
			tool.error("^ not allowed in here for tree-walker", grammar.getFilename(), lit.getLine());
		}
		StringLiteralElement sl = new StringLiteralElement(grammar, lit, autoGenType);

		// If case-insensitive, then check each char of the stirng literal
		if (grammar instanceof LexerGrammar && !((LexerGrammar)grammar).caseSensitive) {
			for (int i = 1; i < lit.getText().length()-1; i++) {
				char c = lit.getText().charAt(i);
				if (c < 128 && Character.toLowerCase(c) != c) {
					tool.warning("Characters of string literal must be lowercase when caseSensitive=false", grammar.getFilename(), lit.getLine());
					break;
				}
			}
		}

		addElementToCurrentAlt(sl);
		labelElement(sl, label);

		// if ignore option is set, must add an optional call to the specified rule.
		String ignore = ruleBlock.getIgnoreRule();
		if ( !lastInRule && ignore!=null ) {
			addElementToCurrentAlt(createOptionalRuleRef(ignore, lit.getLine()));
		}
	}
	public void refToken(Token idAssign, Token t, Token label, Token args,
		boolean inverted, int autoGenType, boolean lastInRule) {
		if (grammar instanceof LexerGrammar) {
			// In lexer, token references are really rule references
			if (autoGenType == GrammarElement.AUTO_GEN_CARET) {
				tool.error("AST specification ^ not allowed in lexer", grammar.getFilename(), t.getLine());
			}
			if (inverted) {
				tool.error("~TOKEN is not allowed in lexer", grammar.getFilename(), t.getLine());
			}
			refRule(idAssign, t, label, args, autoGenType);

			// if ignore option is set, must add an optional call to the specified token rule.
			String ignore = ruleBlock.getIgnoreRule();
			if ( !lastInRule && ignore!=null ) {
				addElementToCurrentAlt(createOptionalRuleRef(ignore, t.getLine()));
			}
		} else {
			// Cannot have token ref args or assignment outside of lexer
			if (idAssign!= null)
			{
				tool.error("Assignment from token reference only allowed in lexer", grammar.getFilename(), idAssign.getLine());
			}
			if (args != null)
			{
				tool.error("Token reference arguments only allowed in lexer", grammar.getFilename(), args.getLine());
			}
			super.refToken(idAssign, t, label, args, inverted, autoGenType, lastInRule);
			TokenRefElement te = new TokenRefElement(grammar, t, inverted, autoGenType);
			addElementToCurrentAlt(te);
			labelElement(te, label);
		}
	}
	public void refTokenRange(Token t1, Token t2, Token label, int autoGenType, boolean lastInRule) {
		if (grammar instanceof LexerGrammar) {
			tool.error("Token range not allowed in lexer", grammar.getFilename(), t1.getLine());
			return;
		}
		super.refTokenRange(t1, t2, label, autoGenType, lastInRule);
		TokenRangeElement tr = new TokenRangeElement(grammar, t1, t2, autoGenType);
		if (tr.end < tr.begin) {
			tool.error("Malformed range.", grammar.getFilename(), t1.getLine());
			return;
		}
		addElementToCurrentAlt(tr);
		labelElement(tr, label);
	}
	public void refTreeSpecifier(Token treeSpec) {
		context().currentAlt().treeSpecifier = treeSpec;
	}
	public void refWildcard(Token t, Token label, int autoGenType) {
		super.refWildcard(t, label, autoGenType);
		WildcardElement wc = new WildcardElement(grammar, t, autoGenType);
		addElementToCurrentAlt(wc);
		labelElement(wc, label);
	}
	/** Get ready to process a new grammar */
	public void reset() {
		super.reset();
		blocks = new LList();
		lastRuleRef = null;
		ruleEnd = null;
		ruleBlock = null;
		nested = 0;
		currentExceptionSpec = null;
		grammarError = false;
	}
	public void setArgOfRuleRef(Token argAction) {
		super.setArgOfRuleRef(argAction);
		lastRuleRef.setArgs(argAction.getText());
	}
	public static void setBlock(AlternativeBlock b, AlternativeBlock src) {
		b.setAlternatives(src.getAlternatives());
		b.initAction = src.initAction;
		//b.lookaheadDepth = src.lookaheadDepth;
		b.label = src.label;
		b.hasASynPred = src.hasASynPred;
		b.hasAnAction = src.hasAnAction;
		b.warnWhenFollowAmbig = src.warnWhenFollowAmbig;
		b.generateAmbigWarnings = src.generateAmbigWarnings;
		b.line = src.line;
		b.greedy = src.greedy;
		b.greedySet = src.greedySet;
	}
	public void setRuleOption(Token key, Token value) {
		//((RuleBlock)context().block).setOption(key, value);
		ruleBlock.setOption(key, value);
	}
	public void setSubruleOption(Token key, Token value) {
		((AlternativeBlock)context().block).setOption(key, value);
	}
	public void synPred() {
		if (context().block.not) {
			tool.error("'~' cannot be applied to syntactc predicate", grammar.getFilename(), context().block.getLine());
		}
		// create the right kind of object now that we know what that is
		// and switch the list of alternatives.  Adjust the stack of blocks.
		// copy any init action also.
		SynPredBlock b = new SynPredBlock(grammar);
		setBlock(b,context().block);
		BlockContext old = (BlockContext)blocks.pop(); // remove old scope; we want new type of subrule
		blocks.push(new BlockContext());
		context().block = b;
		context().blockEnd = old.blockEnd;
		context().blockEnd.block = b;
	}
	public void zeroOrMoreSubRule() {
		if (context().block.not) {
			tool.error("'~' cannot be applied to (...)+ subrule", grammar.getFilename(), context().block.getLine());
		}
		// create the right kind of object now that we know what that is
		// and switch the list of alternatives.  Adjust the stack of blocks.
		// copy any init action also.
		ZeroOrMoreBlock b = new ZeroOrMoreBlock(grammar);
		setBlock(b,context().block);
		BlockContext old = (BlockContext)blocks.pop(); // remove old scope; we want new type of subrule
		blocks.push(new BlockContext());
		context().block = b;
		context().blockEnd = old.blockEnd;
		context().blockEnd.block = b;
	}
}

⌨️ 快捷键说明

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