Merge branch 'model-updates-for-new-targets' of github.com:parrt/antlr4 into reduce-model-changes

This commit is contained in:
parrt 2016-11-05 09:29:25 -07:00
commit abdb0b6a46
5 changed files with 119 additions and 86 deletions

View File

@ -2,6 +2,7 @@
* [The "BSD license"]
* Copyright (c) 2012 Terence Parr
* Copyright (c) 2012 Sam Harwell
* Copyright (c) 2016 Mike Lischke
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -27,7 +28,6 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.antlr.v4.codegen;
import org.antlr.v4.parse.ANTLRParser;
@ -59,8 +59,8 @@ public class CodeGenPipeline {
for (GrammarAST idNode : idNodes) {
if ( gen.getTarget().grammarSymbolCausesIssueInGeneratedCode(idNode) ) {
g.tool.errMgr.grammarError(ErrorType.USE_OF_BAD_WORD,
g.fileName, idNode.getToken(),
idNode.getText());
g.fileName, idNode.getToken(),
idNode.getText());
}
}
@ -70,46 +70,84 @@ public class CodeGenPipeline {
int errorCount = g.tool.errMgr.getNumErrors();
if ( g.isLexer() ) {
ST lexer = gen.generateLexer();
if (gen.getTarget().needsHeader()) {
ST lexer = gen.generateLexer(true); // Header file if needed.
if (g.tool.errMgr.getNumErrors() == errorCount) {
writeRecognizer(lexer, gen, true);
}
}
ST lexer = gen.generateLexer(false);
if (g.tool.errMgr.getNumErrors() == errorCount) {
writeRecognizer(lexer, gen);
writeRecognizer(lexer, gen, false);
}
}
else {
ST parser = gen.generateParser();
if (g.tool.errMgr.getNumErrors() == errorCount) {
writeRecognizer(parser, gen);
}
if ( g.tool.gen_listener ) {
ST listener = gen.generateListener();
if (gen.getTarget().needsHeader()) {
ST parser = gen.generateParser(true);
if (g.tool.errMgr.getNumErrors() == errorCount) {
gen.writeListener(listener);
writeRecognizer(parser, gen, true);
}
}
ST parser = gen.generateParser(false);
if (g.tool.errMgr.getNumErrors() == errorCount) {
writeRecognizer(parser, gen, false);
}
if ( g.tool.gen_listener ) {
if (gen.getTarget().needsHeader()) {
ST listener = gen.generateListener(true);
if (g.tool.errMgr.getNumErrors() == errorCount) {
gen.writeListener(listener, true);
}
}
ST listener = gen.generateListener(false);
if (g.tool.errMgr.getNumErrors() == errorCount) {
gen.writeListener(listener, false);
}
if (gen.getTarget().needsHeader()) {
ST baseListener = gen.generateBaseListener(true);
if (g.tool.errMgr.getNumErrors() == errorCount) {
gen.writeBaseListener(baseListener, true);
}
}
if (gen.getTarget().wantsBaseListener()) {
ST baseListener = gen.generateBaseListener();
if (g.tool.errMgr.getNumErrors() == errorCount) {
gen.writeBaseListener(baseListener);
ST baseListener = gen.generateBaseListener(false);
if ( g.tool.errMgr.getNumErrors()==errorCount ) {
gen.writeBaseListener(baseListener, false);
}
}
}
if ( g.tool.gen_visitor ) {
ST visitor = gen.generateVisitor();
if (gen.getTarget().needsHeader()) {
ST visitor = gen.generateVisitor(true);
if (g.tool.errMgr.getNumErrors() == errorCount) {
gen.writeVisitor(visitor, true);
}
}
ST visitor = gen.generateVisitor(false);
if (g.tool.errMgr.getNumErrors() == errorCount) {
gen.writeVisitor(visitor);
gen.writeVisitor(visitor, false);
}
if (gen.getTarget().needsHeader()) {
ST baseVisitor = gen.generateBaseVisitor(true);
if (g.tool.errMgr.getNumErrors() == errorCount) {
gen.writeBaseVisitor(baseVisitor, true);
}
}
if (gen.getTarget().wantsBaseVisitor()) {
ST baseVisitor = gen.generateBaseVisitor();
if (g.tool.errMgr.getNumErrors() == errorCount) {
gen.writeBaseVisitor(baseVisitor);
ST baseVisitor = gen.generateBaseVisitor(false);
if ( g.tool.errMgr.getNumErrors()==errorCount ) {
gen.writeBaseVisitor(baseVisitor, false);
}
}
}
gen.writeHeaderFile();
}
gen.writeVocabFile();
}
protected void writeRecognizer(ST template, CodeGenerator gen) {
protected void writeRecognizer(ST template, CodeGenerator gen, boolean header) {
if ( g.tool.launch_ST_inspector ) {
STViz viz = template.inspect();
if (g.tool.ST_inspector_wait_for_close) {
@ -122,6 +160,6 @@ public class CodeGenPipeline {
}
}
gen.writeRecognizer(template);
gen.writeRecognizer(template, header);
}
}

View File

@ -2,6 +2,7 @@
* [The "BSD license"]
* Copyright (c) 2012 Terence Parr
* Copyright (c) 2012 Sam Harwell
* Copyright (c) 2016 Mike Lischke
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -134,17 +135,28 @@ public class CodeGenerator {
return controller;
}
private ST walk(OutputModelObject outputModel) {
private ST walk(OutputModelObject outputModel, boolean header) {
OutputModelWalker walker = new OutputModelWalker(tool, getTemplates());
return walker.walk(outputModel);
return walker.walk(outputModel, header);
}
public ST generateLexer() { return walk(createController().buildLexerOutputModel()); }
public ST generateParser() { return walk(createController().buildParserOutputModel()); }
public ST generateListener() { return walk(createController().buildListenerOutputModel()); }
public ST generateBaseListener() { return walk(createController().buildBaseListenerOutputModel()); }
public ST generateVisitor() { return walk(createController().buildVisitorOutputModel()); }
public ST generateBaseVisitor() { return walk(createController().buildBaseVisitorOutputModel()); }
public ST generateLexer() { return generateLexer(false); }
public ST generateLexer(boolean header) { return walk(createController().buildLexerOutputModel(header), header); }
public ST generateParser() { return generateParser(false); }
public ST generateParser(boolean header) { return walk(createController().buildParserOutputModel(header), header); }
public ST generateListener() { return generateListener(false); }
public ST generateListener(boolean header) { return walk(createController().buildListenerOutputModel(header), header); }
public ST generateBaseListener() { return generateBaseListener(false); }
public ST generateBaseListener(boolean header) { return walk(createController().buildBaseListenerOutputModel(header), header); }
public ST generateVisitor() { return generateVisitor(false); }
public ST generateVisitor(boolean header) { return walk(createController().buildVisitorOutputModel(header), header); }
public ST generateBaseVisitor() { return generateBaseVisitor(false); }
public ST generateBaseVisitor(boolean header) { return walk(createController().buildBaseVisitorOutputModel(header), header); }
/** Generate a token vocab file with all the token names/types. For example:
* ID=7
@ -178,35 +190,24 @@ public class CodeGenerator {
return vocabFileST;
}
public void writeRecognizer(ST outputFileST) {
getTarget().genFile(g, outputFileST, getRecognizerFileName());
public void writeRecognizer(ST outputFileST, boolean header) {
getTarget().genFile(g, outputFileST, getRecognizerFileName(header));
}
public void writeListener(ST outputFileST) {
getTarget().genFile(g, outputFileST, getListenerFileName());
public void writeListener(ST outputFileST, boolean header) {
getTarget().genFile(g, outputFileST, getListenerFileName(header));
}
public void writeBaseListener(ST outputFileST) {
getTarget().genFile(g, outputFileST, getBaseListenerFileName());
public void writeBaseListener(ST outputFileST, boolean header) {
getTarget().genFile(g, outputFileST, getBaseListenerFileName(header));
}
public void writeVisitor(ST outputFileST) {
getTarget().genFile(g, outputFileST, getVisitorFileName());
public void writeVisitor(ST outputFileST, boolean header) {
getTarget().genFile(g, outputFileST, getVisitorFileName(header));
}
public void writeBaseVisitor(ST outputFileST) {
getTarget().genFile(g, outputFileST, getBaseVisitorFileName());
}
public void writeHeaderFile() {
String fileName = getHeaderFileName();
if ( fileName==null ) return;
if ( getTemplates().isDefined("headerFile") ) {
ST extST = getTemplates().getInstanceOf("headerFileExtension");
ST headerFileST = null;
// TODO: don't hide this header file generation here!
getTarget().genRecognizerHeaderFile(g, headerFileST, extST.render(lineWidth));
}
public void writeBaseVisitor(ST outputFileST, boolean header) {
getTarget().genFile(g, outputFileST, getBaseVisitorFileName(header));
}
public void writeVocabFile() {

View File

@ -2,6 +2,7 @@
* [The "BSD license"]
* Copyright (c) 2012 Terence Parr
* Copyright (c) 2012 Sam Harwell
* Copyright (c) 2016 Mike Lischke
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -107,24 +108,23 @@ public class OutputModelController {
* controller as factory in SourceGenTriggers so it triggers codegen
* extensions too, not just the factory functions in this factory.
*/
public OutputModelObject buildParserOutputModel() {
Grammar g = delegate.getGrammar();
public OutputModelObject buildParserOutputModel(boolean header) {
CodeGenerator gen = delegate.getGenerator();
ParserFile file = parserFile(gen.getRecognizerFileName());
ParserFile file = parserFile(gen.getRecognizerFileName(header));
setRoot(file);
Parser parser = parser(file);
file.parser = parser;
file.parser = parser(file);
Grammar g = delegate.getGrammar();
for (Rule r : g.rules.values()) {
buildRuleFunction(parser, r);
buildRuleFunction(file.parser, r);
}
return file;
}
public OutputModelObject buildLexerOutputModel() {
public OutputModelObject buildLexerOutputModel(boolean header) {
CodeGenerator gen = delegate.getGenerator();
LexerFile file = lexerFile(gen.getRecognizerFileName());
LexerFile file = lexerFile(gen.getRecognizerFileName(header));
setRoot(file);
file.lexer = lexer(file);
@ -136,24 +136,24 @@ public class OutputModelController {
return file;
}
public OutputModelObject buildListenerOutputModel() {
public OutputModelObject buildListenerOutputModel(boolean header) {
CodeGenerator gen = delegate.getGenerator();
return new ListenerFile(delegate, gen.getListenerFileName());
return new ListenerFile(delegate, gen.getListenerFileName(header));
}
public OutputModelObject buildBaseListenerOutputModel() {
public OutputModelObject buildBaseListenerOutputModel(boolean header) {
CodeGenerator gen = delegate.getGenerator();
return new BaseListenerFile(delegate, gen.getBaseListenerFileName());
return new BaseListenerFile(delegate, gen.getBaseListenerFileName(header));
}
public OutputModelObject buildVisitorOutputModel() {
public OutputModelObject buildVisitorOutputModel(boolean header) {
CodeGenerator gen = delegate.getGenerator();
return new VisitorFile(delegate, gen.getVisitorFileName());
return new VisitorFile(delegate, gen.getVisitorFileName(header));
}
public OutputModelObject buildBaseVisitorOutputModel() {
public OutputModelObject buildBaseVisitorOutputModel(boolean header) {
CodeGenerator gen = delegate.getGenerator();
return new BaseVisitorFile(delegate, gen.getBaseVisitorFileName());
return new BaseVisitorFile(delegate, gen.getBaseVisitorFileName(header));
}
public ParserFile parserFile(String fileName) {

View File

@ -2,6 +2,7 @@
* [The "BSD license"]
* Copyright (c) 2012 Terence Parr
* Copyright (c) 2012 Sam Harwell
* Copyright (c) 2016 Mike Lischke
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -75,7 +76,7 @@ public class OutputModelWalker {
this.templates = templates;
}
public ST walk(OutputModelObject omo) {
public ST walk(OutputModelObject omo, boolean header) {
// CREATE TEMPLATE FOR THIS OUTPUT OBJECT
Class<? extends OutputModelObject> cl = omo.getClass();
String templateName = cl.getSimpleName();
@ -83,6 +84,9 @@ public class OutputModelWalker {
tool.errMgr.toolError(ErrorType.NO_MODEL_TO_TEMPLATE_MAPPING, cl.getSimpleName());
return new ST("["+templateName+" invalid]");
}
if (header) templateName += "Header";
ST st = templates.getInstanceOf(templateName);
if ( st == null ) {
tool.errMgr.toolError(ErrorType.CODE_GEN_TEMPLATES_INCOMPLETE, templateName);
@ -124,7 +128,7 @@ public class OutputModelWalker {
Object o = fi.get(omo);
if ( o instanceof OutputModelObject ) { // SINGLE MODEL OBJECT?
OutputModelObject nestedOmo = (OutputModelObject)o;
ST nestedST = walk(nestedOmo);
ST nestedST = walk(nestedOmo, header);
// System.out.println("set ModelElement "+fieldName+"="+nestedST+" in "+templateName);
st.add(fieldName, nestedST);
}
@ -136,7 +140,7 @@ public class OutputModelWalker {
Collection<?> nestedOmos = (Collection<?>)o;
for (Object nestedOmo : nestedOmos) {
if ( nestedOmo==null ) continue;
ST nestedST = walk((OutputModelObject)nestedOmo);
ST nestedST = walk((OutputModelObject)nestedOmo, header);
// System.out.println("set ModelElement "+fieldName+"="+nestedST+" in "+templateName);
st.add(fieldName, nestedST);
}
@ -145,7 +149,7 @@ public class OutputModelWalker {
Map<?, ?> nestedOmoMap = (Map<?, ?>)o;
Map<Object, ST> m = new LinkedHashMap<Object, ST>();
for (Map.Entry<?, ?> entry : nestedOmoMap.entrySet()) {
ST nestedST = walk((OutputModelObject)entry.getValue());
ST nestedST = walk((OutputModelObject)entry.getValue(), header);
// System.out.println("set ModelElement "+fieldName+"="+nestedST+" in "+templateName);
m.put(entry.getKey(), nestedST);
}

View File

@ -2,6 +2,7 @@
* [The "BSD license"]
* Copyright (c) 2012 Terence Parr
* Copyright (c) 2012 Sam Harwell
* Copyright (c) 2016 Mike Lischke
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -121,20 +122,6 @@ public abstract class Target {
getCodeGenerator().write(outputFileST, fileName);
}
protected void genListenerFile(Grammar g,
ST outputFileST)
{
String fileName = getCodeGenerator().getListenerFileName();
getCodeGenerator().write(outputFileST, fileName);
}
protected void genRecognizerHeaderFile(Grammar g,
ST headerFileST,
String extName) // e.g., ".h"
{
// no header file by default
}
/** Get a meaningful name for a token type useful during code generation.
* Literals without associated names are converted to the string equivalent
* of their integer values. Used to generate x==ID and x==34 type comparisons
@ -573,4 +560,7 @@ public abstract class Target {
public boolean supportsOverloadedMethods() {
return true;
}
/** @since 4.6 */
public boolean needsHeader() { return false; }; // Override in targets that need header files.
}