Exceptions now work on rules. If you specify at least one catch, then it overrides all catches that ANTLR generates. Otherwise, there would be no way to override the generic recognition exception clause.
This commit is contained in:
parent
8a928d4326
commit
01b5510be1
|
@ -1,10 +1,9 @@
|
|||
grammar A;
|
||||
|
||||
s : e ;
|
||||
|
||||
e : e '*' e # Mult
|
||||
| INT # primary
|
||||
;
|
||||
s : INT ;
|
||||
catch[T x] {foo}
|
||||
catch[U y] {bar}
|
||||
finally { xxxxx }
|
||||
|
||||
INT : [0-9]+ ;
|
||||
WS : [ \t\n]+ -> skip ;
|
||||
|
|
|
@ -187,7 +187,7 @@ case <index> : return <actions.(index)>;}; separator="\n">
|
|||
}
|
||||
>>
|
||||
|
||||
RuleFunction(currentRule,code,locals,ruleCtx,altLabelCtxs,namedActions,finallyAction,postamble) ::= <<
|
||||
RuleFunction(currentRule,code,locals,ruleCtx,altLabelCtxs,namedActions,finallyAction,postamble,exceptions) ::= <<
|
||||
|
||||
<ruleCtx>
|
||||
<altLabelCtxs:{l | <altLabelCtxs.(l)>}; separator="\n">
|
||||
|
@ -205,12 +205,15 @@ RuleFunction(currentRule,code,locals,ruleCtx,altLabelCtxs,namedActions,finallyAc
|
|||
<postamble; separator="\n">
|
||||
<namedActions.after>
|
||||
}
|
||||
<currentRule.exceptions>
|
||||
catch (RecognitionException re) {
|
||||
_localctx.exception = re;
|
||||
_errHandler.reportError(this, re);
|
||||
_errHandler.recover(this, re);
|
||||
}
|
||||
<if(exceptions)>
|
||||
<exceptions; separator="\n">
|
||||
<else>
|
||||
catch (RecognitionException re) {
|
||||
_localctx.exception = re;
|
||||
_errHandler.reportError(this, re);
|
||||
_errHandler.recover(this, re);
|
||||
}
|
||||
<endif>
|
||||
finally {
|
||||
<finallyAction>
|
||||
exitRule();
|
||||
|
@ -473,6 +476,12 @@ setState(<p.stateNumber>);
|
|||
if (!(<chunks>)) throw new FailedPredicateException(this, <if(p.msg)><p.msg><else><failChunks><endif>);
|
||||
>>
|
||||
|
||||
ExceptionClause(e, catchArg, catchAction) ::= <<
|
||||
catch (<catchArg>) {
|
||||
<catchAction>
|
||||
}
|
||||
>>
|
||||
|
||||
// lexer actions are not associated with model objects
|
||||
|
||||
LexerSkipCommand() ::= "skip();"
|
||||
|
|
|
@ -29,10 +29,21 @@
|
|||
|
||||
package org.antlr.v4.codegen;
|
||||
|
||||
import org.antlr.v4.codegen.model.*;
|
||||
import org.antlr.v4.codegen.model.Choice;
|
||||
import org.antlr.v4.codegen.model.CodeBlockForAlt;
|
||||
import org.antlr.v4.codegen.model.LabeledOp;
|
||||
import org.antlr.v4.codegen.model.Lexer;
|
||||
import org.antlr.v4.codegen.model.LexerFile;
|
||||
import org.antlr.v4.codegen.model.Parser;
|
||||
import org.antlr.v4.codegen.model.ParserFile;
|
||||
import org.antlr.v4.codegen.model.RuleFunction;
|
||||
import org.antlr.v4.codegen.model.SrcOp;
|
||||
import org.antlr.v4.runtime.misc.IntervalSet;
|
||||
import org.antlr.v4.tool.*;
|
||||
import org.antlr.v4.tool.ast.*;
|
||||
import org.antlr.v4.tool.Alternative;
|
||||
import org.antlr.v4.tool.Rule;
|
||||
import org.antlr.v4.tool.ast.ActionAST;
|
||||
import org.antlr.v4.tool.ast.BlockAST;
|
||||
import org.antlr.v4.tool.ast.GrammarAST;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
@ -84,13 +95,10 @@ public abstract class BlankOutputModelFactory implements OutputModelFactory {
|
|||
// ACTIONS
|
||||
|
||||
@Override
|
||||
public List<SrcOp> action(GrammarAST ast) { return null; }
|
||||
public List<SrcOp> action(ActionAST ast) { return null; }
|
||||
|
||||
@Override
|
||||
public List<SrcOp> forcedAction(GrammarAST ast) { return null; }
|
||||
|
||||
@Override
|
||||
public List<SrcOp> sempred(GrammarAST ast) { return null; }
|
||||
public List<SrcOp> sempred(ActionAST ast) { return null; }
|
||||
|
||||
// BLOCKS
|
||||
|
||||
|
|
|
@ -410,13 +410,13 @@ public class OutputModelController {
|
|||
return ops;
|
||||
}
|
||||
|
||||
public List<SrcOp> action(GrammarAST ast) {
|
||||
public List<SrcOp> action(ActionAST ast) {
|
||||
List<SrcOp> ops = delegate.action(ast);
|
||||
for (CodeGeneratorExtension ext : extensions) ops = ext.action(ops);
|
||||
return ops;
|
||||
}
|
||||
|
||||
public List<SrcOp> sempred(GrammarAST ast) {
|
||||
public List<SrcOp> sempred(ActionAST ast) {
|
||||
List<SrcOp> ops = delegate.sempred(ast);
|
||||
for (CodeGeneratorExtension ext : extensions) ops = ext.sempred(ops);
|
||||
return ops;
|
||||
|
|
|
@ -29,11 +29,25 @@
|
|||
|
||||
package org.antlr.v4.codegen;
|
||||
|
||||
import org.antlr.v4.codegen.model.*;
|
||||
import org.antlr.v4.codegen.model.Choice;
|
||||
import org.antlr.v4.codegen.model.CodeBlockForAlt;
|
||||
import org.antlr.v4.codegen.model.CodeBlockForOuterMostAlt;
|
||||
import org.antlr.v4.codegen.model.LabeledOp;
|
||||
import org.antlr.v4.codegen.model.Lexer;
|
||||
import org.antlr.v4.codegen.model.LexerFile;
|
||||
import org.antlr.v4.codegen.model.OutputModelObject;
|
||||
import org.antlr.v4.codegen.model.Parser;
|
||||
import org.antlr.v4.codegen.model.ParserFile;
|
||||
import org.antlr.v4.codegen.model.RuleFunction;
|
||||
import org.antlr.v4.codegen.model.SrcOp;
|
||||
import org.antlr.v4.codegen.model.decl.CodeBlock;
|
||||
import org.antlr.v4.runtime.misc.IntervalSet;
|
||||
import org.antlr.v4.tool.*;
|
||||
import org.antlr.v4.tool.ast.*;
|
||||
import org.antlr.v4.tool.Alternative;
|
||||
import org.antlr.v4.tool.Grammar;
|
||||
import org.antlr.v4.tool.Rule;
|
||||
import org.antlr.v4.tool.ast.ActionAST;
|
||||
import org.antlr.v4.tool.ast.BlockAST;
|
||||
import org.antlr.v4.tool.ast.GrammarAST;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
@ -76,11 +90,9 @@ public interface OutputModelFactory {
|
|||
|
||||
List<SrcOp> wildcard(GrammarAST ast, GrammarAST labelAST);
|
||||
|
||||
List<SrcOp> action(GrammarAST ast);
|
||||
List<SrcOp> action(ActionAST ast);
|
||||
|
||||
List<SrcOp> forcedAction(GrammarAST ast);
|
||||
|
||||
List<SrcOp> sempred(GrammarAST ast);
|
||||
List<SrcOp> sempred(ActionAST ast);
|
||||
|
||||
Choice getChoiceBlock(BlockAST blkAST, List<CodeBlockForAlt> alts, GrammarAST label);
|
||||
|
||||
|
|
|
@ -30,13 +30,50 @@
|
|||
package org.antlr.v4.codegen;
|
||||
|
||||
import org.antlr.v4.analysis.AnalysisPipeline;
|
||||
import org.antlr.v4.codegen.model.*;
|
||||
import org.antlr.v4.codegen.model.decl.*;
|
||||
import org.antlr.v4.codegen.model.Action;
|
||||
import org.antlr.v4.codegen.model.AddToLabelList;
|
||||
import org.antlr.v4.codegen.model.AltBlock;
|
||||
import org.antlr.v4.codegen.model.Choice;
|
||||
import org.antlr.v4.codegen.model.CodeBlockForAlt;
|
||||
import org.antlr.v4.codegen.model.CodeBlockForOuterMostAlt;
|
||||
import org.antlr.v4.codegen.model.InvokeRule;
|
||||
import org.antlr.v4.codegen.model.LL1AltBlock;
|
||||
import org.antlr.v4.codegen.model.LL1OptionalBlock;
|
||||
import org.antlr.v4.codegen.model.LL1OptionalBlockSingleAlt;
|
||||
import org.antlr.v4.codegen.model.LL1PlusBlock;
|
||||
import org.antlr.v4.codegen.model.LL1PlusBlockSingleAlt;
|
||||
import org.antlr.v4.codegen.model.LL1StarBlock;
|
||||
import org.antlr.v4.codegen.model.LL1StarBlockSingleAlt;
|
||||
import org.antlr.v4.codegen.model.LabeledOp;
|
||||
import org.antlr.v4.codegen.model.LeftRecursiveRuleFunction;
|
||||
import org.antlr.v4.codegen.model.MatchNotSet;
|
||||
import org.antlr.v4.codegen.model.MatchSet;
|
||||
import org.antlr.v4.codegen.model.MatchToken;
|
||||
import org.antlr.v4.codegen.model.OptionalBlock;
|
||||
import org.antlr.v4.codegen.model.Parser;
|
||||
import org.antlr.v4.codegen.model.ParserFile;
|
||||
import org.antlr.v4.codegen.model.PlusBlock;
|
||||
import org.antlr.v4.codegen.model.RuleFunction;
|
||||
import org.antlr.v4.codegen.model.SemPred;
|
||||
import org.antlr.v4.codegen.model.SrcOp;
|
||||
import org.antlr.v4.codegen.model.StarBlock;
|
||||
import org.antlr.v4.codegen.model.TestSetInline;
|
||||
import org.antlr.v4.codegen.model.decl.Decl;
|
||||
import org.antlr.v4.codegen.model.decl.RuleContextDecl;
|
||||
import org.antlr.v4.codegen.model.decl.TokenDecl;
|
||||
import org.antlr.v4.codegen.model.decl.TokenListDecl;
|
||||
import org.antlr.v4.parse.ANTLRParser;
|
||||
import org.antlr.v4.runtime.atn.*;
|
||||
import org.antlr.v4.runtime.atn.DecisionState;
|
||||
import org.antlr.v4.runtime.atn.PlusBlockStartState;
|
||||
import org.antlr.v4.runtime.atn.StarLoopEntryState;
|
||||
import org.antlr.v4.runtime.misc.IntervalSet;
|
||||
import org.antlr.v4.tool.*;
|
||||
import org.antlr.v4.tool.ast.*;
|
||||
import org.antlr.v4.tool.Alternative;
|
||||
import org.antlr.v4.tool.LeftRecursiveRule;
|
||||
import org.antlr.v4.tool.Rule;
|
||||
import org.antlr.v4.tool.ast.ActionAST;
|
||||
import org.antlr.v4.tool.ast.BlockAST;
|
||||
import org.antlr.v4.tool.ast.GrammarAST;
|
||||
import org.antlr.v4.tool.ast.TerminalAST;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
@ -83,10 +120,10 @@ public class ParserFactory extends DefaultOutputModelFactory {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<SrcOp> action(GrammarAST ast) { return list(new Action(this, ast)); }
|
||||
public List<SrcOp> action(ActionAST ast) { return list(new Action(this, ast)); }
|
||||
|
||||
@Override
|
||||
public List<SrcOp> sempred(GrammarAST ast) { return list(new SemPred(this, ast)); }
|
||||
public List<SrcOp> sempred(ActionAST ast) { return list(new SemPred(this, ast)); }
|
||||
|
||||
@Override
|
||||
public List<SrcOp> ruleRef(GrammarAST ID, GrammarAST label, GrammarAST args) {
|
||||
|
|
|
@ -107,10 +107,10 @@ element returns [List<? extends SrcOp> omos]
|
|||
: labeledElement {$omos = $labeledElement.omos;}
|
||||
| atom[null,false] {$omos = $atom.omos;}
|
||||
| subrule {$omos = $subrule.omos;}
|
||||
| ACTION {$omos = controller.action($ACTION);}
|
||||
| SEMPRED {$omos = controller.sempred($SEMPRED);}
|
||||
| ^(ACTION elementOptions) {$omos = controller.action($ACTION);}
|
||||
| ^(SEMPRED elementOptions) {$omos = controller.sempred($SEMPRED);}
|
||||
| ACTION {$omos = controller.action((ActionAST)$ACTION);}
|
||||
| SEMPRED {$omos = controller.sempred((ActionAST)$SEMPRED);}
|
||||
| ^(ACTION elementOptions) {$omos = controller.action((ActionAST)$ACTION);}
|
||||
| ^(SEMPRED elementOptions) {$omos = controller.sempred((ActionAST)$SEMPRED);}
|
||||
;
|
||||
|
||||
labeledElement returns [List<? extends SrcOp> omos]
|
||||
|
|
|
@ -30,20 +30,24 @@
|
|||
package org.antlr.v4.codegen.model;
|
||||
|
||||
import org.antlr.runtime.CommonToken;
|
||||
import org.antlr.v4.codegen.*;
|
||||
import org.antlr.v4.codegen.model.chunk.*;
|
||||
import org.antlr.v4.codegen.ActionTranslator;
|
||||
import org.antlr.v4.codegen.OutputModelFactory;
|
||||
import org.antlr.v4.codegen.model.chunk.ActionChunk;
|
||||
import org.antlr.v4.codegen.model.chunk.ActionTemplate;
|
||||
import org.antlr.v4.codegen.model.chunk.ActionText;
|
||||
import org.antlr.v4.codegen.model.decl.StructDecl;
|
||||
import org.antlr.v4.parse.ANTLRParser;
|
||||
import org.antlr.v4.tool.ast.*;
|
||||
import org.antlr.v4.tool.ast.ActionAST;
|
||||
import org.stringtemplate.v4.ST;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/** */
|
||||
public class Action extends RuleElement {
|
||||
@ModelElement public List<ActionChunk> chunks;
|
||||
|
||||
public Action(OutputModelFactory factory, GrammarAST ast) {
|
||||
public Action(OutputModelFactory factory, ActionAST ast) {
|
||||
super(factory,ast);
|
||||
RuleFunction rf = factory.getCurrentRuleFunction();
|
||||
if (ast != null) {
|
||||
|
|
|
@ -30,12 +30,12 @@
|
|||
package org.antlr.v4.codegen.model;
|
||||
|
||||
import org.antlr.v4.codegen.OutputModelFactory;
|
||||
import org.antlr.v4.tool.ast.GrammarAST;
|
||||
import org.antlr.v4.tool.ast.ActionAST;
|
||||
|
||||
public class ArgAction extends Action {
|
||||
/** Context type of invoked rule */
|
||||
public String ctxType;
|
||||
public ArgAction(OutputModelFactory factory, GrammarAST ast, String ctxType) {
|
||||
public ArgAction(OutputModelFactory factory, ActionAST ast, String ctxType) {
|
||||
super(factory, ast);
|
||||
this.ctxType = ctxType;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
package org.antlr.v4.codegen.model;
|
||||
|
||||
import org.antlr.v4.codegen.OutputModelFactory;
|
||||
import org.antlr.v4.tool.ast.ActionAST;
|
||||
|
||||
public class ExceptionClause extends SrcOp {
|
||||
@ModelElement public Action catchArg;
|
||||
@ModelElement public Action catchAction;
|
||||
|
||||
public ExceptionClause(OutputModelFactory factory,
|
||||
ActionAST catchArg,
|
||||
ActionAST catchAction)
|
||||
{
|
||||
super(factory, catchArg);
|
||||
this.catchArg = new Action(factory, catchArg);
|
||||
this.catchAction = new Action(factory, catchAction);
|
||||
}
|
||||
}
|
|
@ -31,7 +31,7 @@ package org.antlr.v4.codegen.model;
|
|||
|
||||
import org.antlr.v4.codegen.OutputModelFactory;
|
||||
import org.antlr.v4.tool.Grammar;
|
||||
import org.antlr.v4.tool.ast.GrammarAST;
|
||||
import org.antlr.v4.tool.ast.ActionAST;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
@ -45,7 +45,7 @@ public class LexerFile extends OutputFile {
|
|||
namedActions = new HashMap<String, Action>();
|
||||
Grammar g = factory.getGrammar();
|
||||
for (String name : g.namedActions.keySet()) {
|
||||
GrammarAST ast = g.namedActions.get(name);
|
||||
ActionAST ast = g.namedActions.get(name);
|
||||
namedActions.put(name, new Action(factory, ast));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,9 +31,10 @@ package org.antlr.v4.codegen.model;
|
|||
|
||||
import org.antlr.v4.codegen.OutputModelFactory;
|
||||
import org.antlr.v4.tool.Grammar;
|
||||
import org.antlr.v4.tool.ast.GrammarAST;
|
||||
import org.antlr.v4.tool.ast.ActionAST;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/** */
|
||||
public class ParserFile extends OutputFile {
|
||||
|
@ -45,7 +46,7 @@ public class ParserFile extends OutputFile {
|
|||
Grammar g = factory.getGrammar();
|
||||
namedActions = new HashMap<String, Action>();
|
||||
for (String name : g.namedActions.keySet()) {
|
||||
GrammarAST ast = g.namedActions.get(name);
|
||||
ActionAST ast = g.namedActions.get(name);
|
||||
namedActions.put(name, new Action(factory, ast));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,7 +71,6 @@ public class RuleFunction extends OutputModelObject {
|
|||
public String ctxType;
|
||||
public Collection<String> ruleLabels;
|
||||
public Collection<String> tokenLabels;
|
||||
public List<String> exceptions;
|
||||
public ATNState startState;
|
||||
public int index;
|
||||
public Collection<Attribute> args = null;
|
||||
|
@ -85,6 +84,7 @@ public class RuleFunction extends OutputModelObject {
|
|||
@ModelElement public Map<String,AltLabelStructDecl> altLabelCtxs;
|
||||
@ModelElement public Map<String,Action> namedActions;
|
||||
@ModelElement public Action finallyAction;
|
||||
@ModelElement public List<ExceptionClause> exceptions;
|
||||
@ModelElement public List<SrcOp> postamble;
|
||||
|
||||
public RuleFunction(OutputModelFactory factory, Rule r) {
|
||||
|
@ -117,10 +117,13 @@ public class RuleFunction extends OutputModelObject {
|
|||
|
||||
ruleLabels = r.getElementLabelNames();
|
||||
tokenLabels = r.getTokenRefs();
|
||||
for (GrammarAST e : r.exceptions) {
|
||||
// TODO:Made new exception object here!!!
|
||||
ActionAST a = (ActionAST)e.getChild(1);
|
||||
exceptions = Utils.nodesToStrings(r.exceptions);
|
||||
if ( r.exceptions!=null ) {
|
||||
exceptions = new ArrayList<ExceptionClause>();
|
||||
for (GrammarAST e : r.exceptions) {
|
||||
ActionAST catchArg = (ActionAST)e.getChild(0);
|
||||
ActionAST catchAction = (ActionAST)e.getChild(1);
|
||||
exceptions.add(new ExceptionClause(factory, catchArg, catchAction));
|
||||
}
|
||||
}
|
||||
if ( r.finallyAction!=null ) finallyAction = new Action(factory, r.finallyAction);
|
||||
|
||||
|
@ -156,7 +159,7 @@ public class RuleFunction extends OutputModelObject {
|
|||
public void fillNamedActions(OutputModelFactory factory, Rule r) {
|
||||
namedActions = new HashMap<String, Action>();
|
||||
for (String name : r.namedActions.keySet()) {
|
||||
GrammarAST ast = r.namedActions.get(name);
|
||||
ActionAST ast = r.namedActions.get(name);
|
||||
namedActions.put(name, new Action(factory, ast));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ public class SemPred extends Action {
|
|||
|
||||
@ModelElement public List<ActionChunk> failChunks;
|
||||
|
||||
public SemPred(OutputModelFactory factory, GrammarAST ast) {
|
||||
public SemPred(OutputModelFactory factory, ActionAST ast) {
|
||||
super(factory,ast);
|
||||
GrammarAST failNode = ((PredAST)ast).getOptionAST("fail");
|
||||
CodeGenerator gen = factory.getGenerator();
|
||||
|
|
Loading…
Reference in New Issue