/* * ****************************************************************************** * MontiCore Language Workbench * Copyright (c) 2015, MontiCore, All rights reserved. * * This project is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3.0 of the License, or (at your option) any later version. * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this project. If not, see <http://www.gnu.org/licenses/>. * ****************************************************************************** */ package de.monticore.codegen.parser.antlr; import java.nio.file.Path; import java.util.Optional; import org.antlr.v4.Tool; import org.antlr.v4.tool.ANTLRMessage; import org.antlr.v4.tool.Grammar; import org.antlr.v4.tool.ast.GrammarRootAST; import org.stringtemplate.v4.ST; import com.google.common.base.Preconditions; import de.monticore.grammar.symboltable.MCGrammarSymbol; import de.monticore.grammar.symboltable.MCProdSymbol; import de.se_rwth.commons.SourcePosition; import de.se_rwth.commons.StringTransformations; import de.se_rwth.commons.logging.Log; /** * ANTLR parser generator * * @author (last commit) $Author$ * @version $Revision$, $Date$ */ public class AntlrTool extends Tool { private MCGrammarSymbol grammarSymbol; public AntlrTool(String[] args, MCGrammarSymbol grammarSymbol, Path outputDir) { super(args); this.grammarSymbol = grammarSymbol; Preconditions.checkArgument(outputDir.toFile().exists(), "The potput directory for AntlrTool " + outputDir + " doesn't exist."); this.outputDirectory = outputDir.toString(); this.haveOutputDir = true; handleArgs(); } @Override public void error(ANTLRMessage message) { createMessage(message, true); } @Override public void warning(ANTLRMessage message) { createMessage(message, false); } /** * Parses the given ANTLR grammar and generates parser * * @param inputFile - ANTLR grammar */ public void createParser(String inputFile) { Grammar grammar = parseAntlrFile(inputFile); generateParser(grammar); } /** * Creates a grammar object associated with the ANTLR grammar AST. * * @param inputFile - ANTLR grammar * @return a grammar object associated with the ANTLR grammar AST */ public Grammar parseAntlrFile(String inputFile) { GrammarRootAST ast = parseGrammar(inputFile); Grammar grammar = createGrammar(ast); grammar.fileName = inputFile; return grammar; } /** * Generates ANTLR Parser * * @param antlrGrammar */ public void generateParser(Grammar antlrGrammar) { process(antlrGrammar, true); } /** * Prints a message in MC style * * @param message * @param isError */ private void createMessage(ANTLRMessage message, boolean isError) { // Set default position SourcePosition position = SourcePosition.getDefaultSourcePosition(); ST msgST = errMgr.getMessageTemplate(message); String origMessage = msgST.render(); Log.debug(origMessage, "AnltrTool"); // Change arguments corresponding to names in MC grammar Object[] args = message.getArgs(); for (int i = 0; i < args.length; i++) { if (args[i] instanceof String) { String name = StringTransformations.capitalize((String) args[i]); Optional<MCProdSymbol> rule = grammarSymbol.getProd(name); if (rule.isPresent()) { args[i] = name; if (i == 0) { position = rule.get().getSourcePosition(); } } } } // Create message ST messageST = message.getMessageTemplate(false); String output = "0xA0129 " + messageST.render(); // Print message if (isError) { if (position.equals(SourcePosition.getDefaultSourcePosition())) { Log.error(output); } else { Log.error(output, position); } } else { if (position.equals(SourcePosition.getDefaultSourcePosition())) { Log.warn(output); } else { Log.warn(output, position); } } } }