/** * Copyright 2004-2016 Riccardo Solmi. All rights reserved. * This file is part of the Whole Platform. * * The Whole Platform 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 of the License, or * (at your option) any later version. * * The Whole Platform 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 the Whole Platform. If not, see <http://www.gnu.org/licenses/>. */ package org.whole.lang.grammars; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.whole.lang.bindings.BindingManagerFactory; import org.whole.lang.grammars.factories.GrammarsEntityFactory; import org.whole.lang.grammars.model.DataTypeEnum; import org.whole.lang.grammars.model.Format; import org.whole.lang.grammars.model.NonTerminal; import org.whole.lang.grammars.model.Template; import org.whole.lang.iterators.IEntityIterator; import org.whole.lang.iterators.IteratorFactory; import org.whole.lang.model.IEntity; import org.whole.lang.util.DataTypeUtils; import org.whole.lang.util.FreshNameGenerator; import org.whole.lang.util.StringUtils; /** * @author Enrico Persiani */ public class GrammarsActionsHelpers { public static IEntity createTuple() { return BindingManagerFactory.instance.createTuple(); } public static void addTokenName(IEntity tokens, IEntity tokenName) { tokens.wAdd(tokenName); } public static IEntity nextTokenFreshName(FreshNameGenerator featureNameGenerator) { return GrammarsEntityFactory.instance.createNonTerminal(featureNameGenerator.nextFreshName("TOKEN")); } public static void addBoundName(FreshNameGenerator featureNameGenerator, String name) { try { featureNameGenerator.addBoundName(name); } catch (Exception e) { // ignore failures } } public static void addBoundNames(FreshNameGenerator featureNameGenerator, AlphaRenameMap aplphaRenameMap) { for (String name : aplphaRenameMap.nameSet()) featureNameGenerator.addBoundName(name); } public static String nextFeatureFreshName(FreshNameGenerator featureNameGenerator, String name) { return featureNameGenerator.nextFreshName(StringUtils.toLowerPrefix(name)); } public static class TokenSet extends HashSet<String> { private static final long serialVersionUID = 1L; public TokenSet() { } public TokenSet(Collection<? extends String> c) { super(c); } public TokenSet(int initialCapacity, float loadFactor) { super(initialCapacity, loadFactor); } public TokenSet(int initialCapacity) { super(initialCapacity); } public TokenSet(IEntity tuple) { this(tuple.wSize()*2); IEntityIterator<NonTerminal> i = IteratorFactory.<NonTerminal>childIterator(); i.reset(tuple); for (NonTerminal nt : i) add(nt.getValue()); } @Override public boolean add(String o) { return super.add(o); } public boolean contains(String s) { return super.contains(s); } public boolean remove(String s) { return super.remove(s); } public boolean add(NonTerminal nt) { return super.add(DataTypeUtils.getAsPresentationString(nt)); } public boolean contains(NonTerminal nt) { return super.contains(DataTypeUtils.getAsPresentationString(nt)); } public boolean remove(NonTerminal nt) { return super.remove(DataTypeUtils.getAsPresentationString(nt)); } } public static class AlphaRenameMap { private Map<String, Set<NonTerminal>> occurenceMap; public AlphaRenameMap() { occurenceMap = new HashMap<String, Set<NonTerminal>>(); } public IEntity names() { IEntity tuple = BindingManagerFactory.instance.createTuple(); for (String name : nameSet()) tuple.wAdd(BindingManagerFactory.instance.createValue(name)); return tuple; } public Set<String> nameSet() { return Collections.unmodifiableSet(occurenceMap.keySet()); } public void add(NonTerminal nt) { String name = DataTypeUtils.getAsPresentationString(nt); getOccurrences(name).add(nt); } public Set<NonTerminal> getOccurrences(String name) { Set<NonTerminal> occurences = occurenceMap.get(name); if (occurences == null) { occurences = new HashSet<NonTerminal>(); occurenceMap.put(name, occurences); } return occurences; } public void rename(String oldName, String newName) { Set<NonTerminal> occurrences = occurenceMap.remove(oldName); if (occurrences == null) return; for (NonTerminal nt : occurrences) DataTypeUtils.setFromPresentationString(nt, newName); occurenceMap.put(newName, occurrences); } } private static final Pattern formatPattern = Pattern.compile("%(\\d+\\$)?([-#+ 0,(\\<]*)?(\\d+)?(\\.\\d+)?" + "(([bBhHsScCdoxXeEfgGaAn%])|([tT](?:[a-zA-Z])?))"); public static Template calculateDataType(Format format) { GrammarsEntityFactory gef = GrammarsEntityFactory.instance; Matcher matcher = formatPattern.matcher(format.getValue()); while (matcher.find()) { String conversion = null; int groupCount = matcher.groupCount(); while ((conversion = matcher.group(groupCount--)) == null) ; switch (conversion.charAt(0)) { case 'b': case 'B': return gef.createDataType(DataTypeEnum.BOOLEAN); case 'h': case 'H': return gef.createCustomDataType("java.lang.Object"); case 's': case 'S': return gef.createDataType(DataTypeEnum.STRING); case 'c': case 'C': return gef.createDataType(DataTypeEnum.CHAR); case 'd': case 'o': case 'x': case 'X': return gef.createDataType(DataTypeEnum.INT); case 'e': case 'E': case 'f': case 'g': case 'G': case 'a': case 'A': return gef.createDataType(DataTypeEnum.FLOAT); case 't': case 'T': return gef.createDataType(DataTypeEnum.DATE); } } return gef.createDataType(DataTypeEnum.STRING); } }