From 01b5510be11274a4c8f2ac946b24daa331633350 Mon Sep 17 00:00:00 2001 From: Terence Parr Date: Sat, 22 Sep 2012 11:58:41 -0700 Subject: [PATCH] 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. --- tool/playground/A.g4 | 9 ++-- .../v4/tool/templates/codegen/Java/Java.stg | 23 ++++++--- .../v4/codegen/BlankOutputModelFactory.java | 24 ++++++--- .../v4/codegen/OutputModelController.java | 4 +- .../antlr/v4/codegen/OutputModelFactory.java | 26 +++++++--- .../org/antlr/v4/codegen/ParserFactory.java | 51 ++++++++++++++++--- .../org/antlr/v4/codegen/SourceGenTriggers.g | 8 +-- .../org/antlr/v4/codegen/model/Action.java | 14 +++-- .../org/antlr/v4/codegen/model/ArgAction.java | 4 +- .../v4/codegen/model/ExceptionClause.java | 18 +++++++ .../org/antlr/v4/codegen/model/LexerFile.java | 4 +- .../antlr/v4/codegen/model/ParserFile.java | 7 +-- .../antlr/v4/codegen/model/RuleFunction.java | 15 +++--- .../org/antlr/v4/codegen/model/SemPred.java | 2 +- 14 files changed, 150 insertions(+), 59 deletions(-) create mode 100644 tool/src/org/antlr/v4/codegen/model/ExceptionClause.java diff --git a/tool/playground/A.g4 b/tool/playground/A.g4 index e8648ab63..31ab0037d 100644 --- a/tool/playground/A.g4 +++ b/tool/playground/A.g4 @@ -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 ; diff --git a/tool/resources/org/antlr/v4/tool/templates/codegen/Java/Java.stg b/tool/resources/org/antlr/v4/tool/templates/codegen/Java/Java.stg index ca0e56979..8710dd2a5 100644 --- a/tool/resources/org/antlr/v4/tool/templates/codegen/Java/Java.stg +++ b/tool/resources/org/antlr/v4/tool/templates/codegen/Java/Java.stg @@ -187,7 +187,7 @@ case : return ;}; separator="\n"> } >> -RuleFunction(currentRule,code,locals,ruleCtx,altLabelCtxs,namedActions,finallyAction,postamble) ::= << +RuleFunction(currentRule,code,locals,ruleCtx,altLabelCtxs,namedActions,finallyAction,postamble,exceptions) ::= << }; separator="\n"> @@ -205,12 +205,15 @@ RuleFunction(currentRule,code,locals,ruleCtx,altLabelCtxs,namedActions,finallyAc } - - catch (RecognitionException re) { - _localctx.exception = re; - _errHandler.reportError(this, re); - _errHandler.recover(this, re); - } + + + + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { exitRule(); @@ -473,6 +476,12 @@ setState(); if (!()) throw new FailedPredicateException(this, ); >> +ExceptionClause(e, catchArg, catchAction) ::= << +catch () { + +} +>> + // lexer actions are not associated with model objects LexerSkipCommand() ::= "skip();" diff --git a/tool/src/org/antlr/v4/codegen/BlankOutputModelFactory.java b/tool/src/org/antlr/v4/codegen/BlankOutputModelFactory.java index 2f92a38ba..8533df88e 100644 --- a/tool/src/org/antlr/v4/codegen/BlankOutputModelFactory.java +++ b/tool/src/org/antlr/v4/codegen/BlankOutputModelFactory.java @@ -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 action(GrammarAST ast) { return null; } + public List action(ActionAST ast) { return null; } @Override - public List forcedAction(GrammarAST ast) { return null; } - - @Override - public List sempred(GrammarAST ast) { return null; } + public List sempred(ActionAST ast) { return null; } // BLOCKS diff --git a/tool/src/org/antlr/v4/codegen/OutputModelController.java b/tool/src/org/antlr/v4/codegen/OutputModelController.java index 3d32ba927..c928d7399 100644 --- a/tool/src/org/antlr/v4/codegen/OutputModelController.java +++ b/tool/src/org/antlr/v4/codegen/OutputModelController.java @@ -410,13 +410,13 @@ public class OutputModelController { return ops; } - public List action(GrammarAST ast) { + public List action(ActionAST ast) { List ops = delegate.action(ast); for (CodeGeneratorExtension ext : extensions) ops = ext.action(ops); return ops; } - public List sempred(GrammarAST ast) { + public List sempred(ActionAST ast) { List ops = delegate.sempred(ast); for (CodeGeneratorExtension ext : extensions) ops = ext.sempred(ops); return ops; diff --git a/tool/src/org/antlr/v4/codegen/OutputModelFactory.java b/tool/src/org/antlr/v4/codegen/OutputModelFactory.java index 11f28c167..21d640161 100644 --- a/tool/src/org/antlr/v4/codegen/OutputModelFactory.java +++ b/tool/src/org/antlr/v4/codegen/OutputModelFactory.java @@ -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 wildcard(GrammarAST ast, GrammarAST labelAST); - List action(GrammarAST ast); + List action(ActionAST ast); - List forcedAction(GrammarAST ast); - - List sempred(GrammarAST ast); + List sempred(ActionAST ast); Choice getChoiceBlock(BlockAST blkAST, List alts, GrammarAST label); diff --git a/tool/src/org/antlr/v4/codegen/ParserFactory.java b/tool/src/org/antlr/v4/codegen/ParserFactory.java index 8fb79357a..d26eddf35 100644 --- a/tool/src/org/antlr/v4/codegen/ParserFactory.java +++ b/tool/src/org/antlr/v4/codegen/ParserFactory.java @@ -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 action(GrammarAST ast) { return list(new Action(this, ast)); } + public List action(ActionAST ast) { return list(new Action(this, ast)); } @Override - public List sempred(GrammarAST ast) { return list(new SemPred(this, ast)); } + public List sempred(ActionAST ast) { return list(new SemPred(this, ast)); } @Override public List ruleRef(GrammarAST ID, GrammarAST label, GrammarAST args) { diff --git a/tool/src/org/antlr/v4/codegen/SourceGenTriggers.g b/tool/src/org/antlr/v4/codegen/SourceGenTriggers.g index b7adef656..5e88fb4db 100644 --- a/tool/src/org/antlr/v4/codegen/SourceGenTriggers.g +++ b/tool/src/org/antlr/v4/codegen/SourceGenTriggers.g @@ -107,10 +107,10 @@ element returns [List 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 omos] diff --git a/tool/src/org/antlr/v4/codegen/model/Action.java b/tool/src/org/antlr/v4/codegen/model/Action.java index c0912b1fc..8e4d16662 100644 --- a/tool/src/org/antlr/v4/codegen/model/Action.java +++ b/tool/src/org/antlr/v4/codegen/model/Action.java @@ -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 chunks; - public Action(OutputModelFactory factory, GrammarAST ast) { + public Action(OutputModelFactory factory, ActionAST ast) { super(factory,ast); RuleFunction rf = factory.getCurrentRuleFunction(); if (ast != null) { diff --git a/tool/src/org/antlr/v4/codegen/model/ArgAction.java b/tool/src/org/antlr/v4/codegen/model/ArgAction.java index e8fffef61..7680f2aa4 100644 --- a/tool/src/org/antlr/v4/codegen/model/ArgAction.java +++ b/tool/src/org/antlr/v4/codegen/model/ArgAction.java @@ -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; } diff --git a/tool/src/org/antlr/v4/codegen/model/ExceptionClause.java b/tool/src/org/antlr/v4/codegen/model/ExceptionClause.java new file mode 100644 index 000000000..939394165 --- /dev/null +++ b/tool/src/org/antlr/v4/codegen/model/ExceptionClause.java @@ -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); + } +} diff --git a/tool/src/org/antlr/v4/codegen/model/LexerFile.java b/tool/src/org/antlr/v4/codegen/model/LexerFile.java index 4bb197192..946da5110 100644 --- a/tool/src/org/antlr/v4/codegen/model/LexerFile.java +++ b/tool/src/org/antlr/v4/codegen/model/LexerFile.java @@ -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(); 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)); } } diff --git a/tool/src/org/antlr/v4/codegen/model/ParserFile.java b/tool/src/org/antlr/v4/codegen/model/ParserFile.java index 77b416b3a..da668ccbd 100644 --- a/tool/src/org/antlr/v4/codegen/model/ParserFile.java +++ b/tool/src/org/antlr/v4/codegen/model/ParserFile.java @@ -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(); 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)); } } diff --git a/tool/src/org/antlr/v4/codegen/model/RuleFunction.java b/tool/src/org/antlr/v4/codegen/model/RuleFunction.java index cbd0c579a..299d1f0a7 100644 --- a/tool/src/org/antlr/v4/codegen/model/RuleFunction.java +++ b/tool/src/org/antlr/v4/codegen/model/RuleFunction.java @@ -71,7 +71,6 @@ public class RuleFunction extends OutputModelObject { public String ctxType; public Collection ruleLabels; public Collection tokenLabels; - public List exceptions; public ATNState startState; public int index; public Collection args = null; @@ -85,6 +84,7 @@ public class RuleFunction extends OutputModelObject { @ModelElement public Map altLabelCtxs; @ModelElement public Map namedActions; @ModelElement public Action finallyAction; + @ModelElement public List exceptions; @ModelElement public List 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(); + 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(); 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)); } } diff --git a/tool/src/org/antlr/v4/codegen/model/SemPred.java b/tool/src/org/antlr/v4/codegen/model/SemPred.java index c064d26f0..c3ebe96e7 100644 --- a/tool/src/org/antlr/v4/codegen/model/SemPred.java +++ b/tool/src/org/antlr/v4/codegen/model/SemPred.java @@ -45,7 +45,7 @@ public class SemPred extends Action { @ModelElement public List 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();