/*
* ******************************************************************************
* 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 java.util.HashMap;
import java.util.Map;
import java.util.Set;
import de.monticore.grammar.symboltable.MCGrammarSymbol;
import de.se_rwth.commons.logging.Log;
/**
* Class generates human readable names for Lexersymbols
*
* @author krahn
*/
public class LexNamer {
private int j = 0;
private Map<String, String> usedLex = new HashMap<String, String>();
private Map<String, String> usedConstants = new HashMap<String, String>();
private static Map<String, String> goodNames = null;
public LexNamer() {}
public static Map<String, String> getGoodNames() {
if (goodNames == null) {
goodNames = new HashMap<String, String>();
// Put all common names here, one character only, since all others are
// concatanation of these
goodNames.put(";", "SEMI");
goodNames.put("@", "AT");
goodNames.put("#", "HASH");
goodNames.put(".", "POINT");
goodNames.put(",", "COMMA");
goodNames.put("?", "QUESTION");
goodNames.put("ยง", "LEX");
goodNames.put("\"", "QUOTE");
goodNames.put("'", "APOSTROPHE");
goodNames.put("$", "DOLLAR");
goodNames.put("~", "TILDE");
goodNames.put(">", "GT");
goodNames.put("<", "LT");
goodNames.put("=", "EQUALS");
goodNames.put("+", "PLUS");
goodNames.put("++", "PLUSPLUS");
goodNames.put("-", "MINUS");
goodNames.put("*", "STAR");
goodNames.put("%", "PERCENT");
goodNames.put("/", "SLASH");
goodNames.put("&", "AND");
goodNames.put("|", "PIPE");
goodNames.put(":", "COLON");
goodNames.put("!", "EXCLAMATIONMARK");
goodNames.put("^", "ROOF");
// Don't change the following, unless you change Grammar2Antlr too
goodNames.put("(", "LPAREN");
goodNames.put(")", "RPAREN");
goodNames.put("[", "LBRACK");
goodNames.put("]", "RBRACK");
goodNames.put("{", "LCURLY");
goodNames.put("}", "RCURLY");
}
return goodNames;
}
/**
* Returns a good name for the lex symbol, or null it is not posssible
*/
public static String createGoodName(String x) {
StringBuilder ret = new StringBuilder();
if (x.matches("[a-zA-Z]+")) {
return x.toUpperCase();
}
for (int i = 0; i < x.length(); i++) {
String substring = x.substring(i, i + 1);
if (getGoodNames().containsKey(substring)) {
ret.append(getGoodNames().get(substring));
}
else {
ret = null;
break;
}
}
if (ret != null) {
return ret.toString();
}
else
return null;
}
/**
* Returns Human-Readable, antlr conformed name for a lexsymbols nice names for common tokens
* (change constructor to add tokenes) LEXi where i is number for unknown ones
*
* @param sym lexer symbol
* @return Human-Readable, antlr conformed name for a lexsymbols
*/
public String getLexName(MCGrammarSymbol grammarSymbol, String sym) {
if (usedLex.containsKey(sym)) {
return usedLex.get(sym);
}
String goodName = createGoodName(sym);
if (goodName != null && !grammarSymbol.getProd(goodName).isPresent()) {
usedLex.put(sym, goodName);
Log.debug("Using lexer symbol " + goodName + " for symbol '" + sym + "'", "LexNamer");
return goodName;
}
return "'" + sym + "'";
}
public String getConstantName(String sym) {
String s = sym.intern();
if (!usedConstants.containsKey(s)) {
String goodName = createGoodName(s);
if (goodName != null) {
usedConstants.put(s, goodName);
}
else {
usedConstants.put(s, ("CONSTANT" + j++).intern());
}
}
String name = usedConstants.get(sym.intern());
Log.debug("Using lexer constant " + name + " for symbol '" + s + "'", "LexNamer");
return name;
}
public Set<String> getLexnames() {
return usedLex.keySet();
}
}