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 + -
显示快捷键?