/* * ****************************************************************************** * 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.grammar; import com.google.common.collect.Lists; import de.monticore.grammar.grammar._ast.*; import de.monticore.grammar.prettyprint.Grammar_WithConceptsPrettyPrinter; import de.se_rwth.commons.JavaNamesHelper; import de.se_rwth.commons.Names; import de.se_rwth.commons.StringTransformations; import de.se_rwth.commons.logging.Log; import java.util.List; /** * Some helper methods for GrammarDSL * * @author krahn */ public class HelperGrammar { /** * The result is true iff ASTTerminal is iterated * * @param a ASTConstantGroup to be evaluated * @return true iff ASTConstantGroup is iterated */ public static boolean isIterated(ASTTerminal a) { return (a.getIteration() == ASTConstantsGrammar.PLUS) || (a.getIteration() == ASTConstantsGrammar.STAR); } /** * The result is true iff ASTOrGroup is iterated * * @param a ASTOrGroup to be evaluated * @return true iff ASTOrGroup is iterated */ public static boolean isIterated(ASTBlock a) { return ((a.getIteration() == ASTConstantsGrammar.PLUS) || (a.getIteration() == ASTConstantsGrammar.STAR)); } /** * Returns the name of a rule * * @param a rule * @return Name of a rule */ public static String getRuleName(ASTClassProd a) { return a.getName(); } /** * Creates usuage name from a NtSym usually from its attribute or creates name * * @param a * @return */ public static String getUsuageName(ASTNonTerminal a) { String name; if (a.getUsageName().isPresent()) { name = a.getUsageName().get(); } else { // Use Nonterminal name as attribute name starting with lower case // latter name = StringTransformations.uncapitalize(a.getName()); } return name; } public static boolean isIterated(ASTNonTerminal a) { return ((a.getIteration() == ASTConstantsGrammar.PLUS) || (a.getIteration() == ASTConstantsGrammar.STAR)); } public static String getTypeNameForEnum(String surroundtype, ASTConstantGroup a) { return "[enum." + surroundtype + "." + a.getUsageName(); } /** * Creates the convert function for a lexrule * * @param a * @return */ public static String createConvertFunction(ASTLexProd a, Grammar_WithConceptsPrettyPrinter prettyPrinter) { String name = a.getName(); // simple String if (!a.getVariable().isPresent()) { return createStringConvertFunction(name); } // default functions else if (a.getType() == null || a.getType().isEmpty()) { String variable = a.getVariable().get(); if ("int".equals(variable)) { String function = "private int convert%name%(Token t) {\n" + " return Integer.parseInt(t.getText());\n" + " }\n"; return createConvertFunction(name, function); } else if ("boolean".equals(variable)) { return createConvertFunction( name, "private boolean convert" + name + "(Token t) {\n" + " if (t.getText().equals(\"1\")||t.getText().equals(\"start\")||t.getText().equals(\"on\")||t.getText().equals(\"true\")){return true;}else{return false;} \n" + "}\n"); } else if ("byte".equals(variable)) { String function = "private byte convert%name%(Token t) {\n" + " return Byte.parseByte(t.getText());\n" + " }\n"; return createConvertFunction(name, function); } else if ("char".equals(variable)) { return createConvertFunction(name, "private char convert" + name + "(Token t) " + "{\n" + " return t.getText().charAt(0); \n" + "}\n"); } else if ("float".equals(variable)) { String function = "private float convert%name%(Token t) {\n" + " return Float.parseFloat(t.getText());\n" + " }\n"; return createConvertFunction(name, function); } else if ("double".equals(variable)) { String function = "private double convert%name%(Token t) {\n" + " return Double.parseDouble(t.getText());\n" + " }\n"; return createConvertFunction(name, function); } else if ("long".equals(variable)) { String function = "private long convert%name%(Token t) {\n" + " return Long.parseLong(t.getText());\n" + " }\n"; return createConvertFunction(name, function); } else if ("short".equals(variable)) { String function = "private short convert%name%(Token t) {\n" + "return Short.parseShort(t.getText());\n" + " }\n"; return createConvertFunction(name, function); } else if ("card".equals(variable)) { String function = "private int convert%name%(Token t) {\n" + " if (t.getText().equals(\"*\")) return -1; else return Integer.parseInt(t.getText());\n" + " }\n"; return createConvertFunction(name, function); } else { Log.warn( "0xA1061 No function for " + a.getVariable() + " registered, will treat it as string!"); return createStringConvertFunction(name); } } // specific function else { if (a.getBlock().isPresent()) { StringBuilder buffer = new StringBuilder(); buffer.append(prettyPrinter.prettyprint(a.getBlock().get())); String createConvertFunction = createConvertFunction(name, "private " + Names.getQualifiedName(a.getType()) + " convert" + name + "(Token " + a.getVariable().get() + ")" + " {\n" + buffer.toString() + "}\n"); return createConvertFunction; } } return ""; } private static String createConvertFunction(String name, String function) { String f = function.replaceAll("%name%", name); return "// convert function for " + name + "\n" + f; } public static String createStringConvertFunction(String name) { String t = "private String convert" + name + "(Token t) {\n" + " return t.getText();\n" + "}\n"; return "// convert function for " + name + "\n" + t; } public static String createConvertType(ASTLexProd a) { if (!a.getVariable().isPresent()) { return "String"; } String variable = a.getVariable().get(); String name = a.getName(); // simple String // default functions if (a.getType() == null || a.getType().isEmpty()) { if ("int".equals(variable) || "boolean".equals(variable) || "char".equals(variable) || "float".equals(variable) || "double".equals(variable) || "long".equals(variable) || "byte".equals(variable) || "short".equals(variable)) { return variable; } else if (variable.equals("card")) { return "int"; } else { Log.warn( "0xA1032 No function for " + a.getVariable() + " registered, will treat it as string!"); return createStringConvertFunction(name); } } // specific function else { return Names.getQualifiedName(a.getType()); } } /** * Printable representation of iteration * * @param i Value from AST * @return String representing value i */ public static String printIteration(int i) { switch (i) { case ASTConstantsGrammar.PLUS: return "+"; case ASTConstantsGrammar.STAR: return "*"; case ASTConstantsGrammar.QUESTION: return "?"; default: return ""; } } public static String printGenericType(ASTGenericType genericType) { StringBuilder b = new StringBuilder(); b.append(Names.getQualifiedName(genericType.getNames())); boolean first = true; for (ASTGenericType t : genericType.getGenericTypes()) { if (first) { b.append("<"); first = false; } else { b.append(","); } b.append(printGenericType(t)); } if (!first) { b.append(">"); } int dimension = genericType.getDimension(); for (int i = dimension; i > 0; i--) { b.append("[]"); } return b.toString(); } public static boolean hasValidName(ASTConstant astConstant) { if (astConstant.getHumanName().isPresent()) { return true; } String constName = astConstant.getName(); if (constName == null || constName.isEmpty()) { return false; } if (!matchesJavaIdentifier(constName) && LexNamer.createGoodName(constName) == null) { return false; } return true; } public static boolean matchesJavaIdentifier(String checkedString) { if (checkedString == null || checkedString.length() == 0) { return false; } char[] stringAsChars = checkedString.toCharArray(); if (!Character.isJavaIdentifierStart(stringAsChars[0])) { return false; } for (int i = 1; i < stringAsChars.length; i++) { if (!Character.isJavaIdentifierPart(stringAsChars[i])) { return false; } } return true; } public static String getAttributeNameForConstant(ASTConstant astConstant) { String name; if (astConstant.getHumanName().isPresent()) { name = astConstant.getHumanName().get(); } else { String constName = astConstant.getName(); if (matchesJavaIdentifier(constName)) { name = constName; } else { name = LexNamer.createGoodName(constName); if (name == null) { name = constName; } } } return name; } /** * Returns Human-Readable, antlr conformed name for a rulename * * @param rulename rule name * @return Human-Readable, antlr conformed rule name */ public static String getRuleNameForAntlr(String rulename) { return JavaNamesHelper.getNonReservedName(StringTransformations.uncapitalize(rulename)); } /** * Returns Human-Readable, antlr conformed name for a rulename * * @return Human-Readable, antlr conformed rule name */ public static String getRuleNameForAntlr(ASTClassProd rule) { String s = getRuleNameForAntlr(HelperGrammar.getRuleName(rule)); return s; } /** * Returns Human-Readable, antlr conformed name for a rulename * * @return Human-Readable, antlr conformed rule name */ public static String getRuleNameForAntlr(ASTNonTerminal ntsym) { String s = getRuleNameForAntlr(ntsym.getName()); return s; } public static List<String> findImplicitTypes(ASTLexActionOrPredicate action, Grammar_WithConceptsPrettyPrinter prettyPrinter) { List<String> ret = Lists.newArrayList(); StringBuilder buffer = new StringBuilder(); buffer.append(prettyPrinter.prettyprint(action.getExpressionPredicate())); String actionText = buffer.toString(); if (actionText.contains("_ttype")) { String[] split = actionText.split("_ttype"); for (int i = 1; i < split.length; i++) { String rest = split[i].trim(); if (rest.length() > 1 && rest.startsWith("=")) { rest = rest.substring(1).trim(); if (!rest.startsWith("Token")) { String string = rest.split("[ ;]")[0]; ret.add(string); } } } } if (actionText.contains("$setType(")) { String[] split = actionText.split("[$]setType[(]"); for (int i = 1; i < split.length; i++) { String rest = split[i].trim(); if (rest.length() > 0) { if (!rest.startsWith("Token")) { String string = rest.split("[ )]")[0]; ret.add(string); } } } } return ret; } }