//This file is part of SECONDO. //Copyright (C) 2004, University in Hagen, Department of Computer Science, //Database Systems for New Applications. //SECONDO is free software; you can redistribute it and/or modify //it under the terms of the GNU General Public License as published by //the Free Software Foundation; either version 2 of the License, or //(at your option) any later version. //SECONDO 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 General Public License for more details. //You should have received a copy of the GNU General Public License //along with SECONDO; if not, write to the Free Software //Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package util.common; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.regex.Matcher; import java.util.regex.Pattern; import util.domain.Operator; import util.domain.enums.BracketType; import util.domain.enums.Delimiter; import util.domain.enums.OperatorType; import util.domain.enums.ParameterType; /** * Parses the operator definition file of secondo and stores * all relevant information in objects of type {@link Operator} * @author D.Merle */ public class OperatorSpecParser { private static final Pattern ARGUMENT_PATTERN = Pattern.compile("funlist|fun|list|_|,|;"); /** * * @param filePath * @return * @throws IOException */ public static HashMap parse(final String filePath) throws IOException { final HashMap operators = new HashMap<>(); final Pattern pattern = Pattern.compile("operator (.*) alias (.*) pattern (.*)"); FileReader fileReader; try { fileReader = new FileReader(new File(filePath)); try (BufferedReader bufferedReader = new BufferedReader(fileReader)) { String line = bufferedReader.readLine(); while (line != null) { final Matcher matcher = pattern.matcher(line); if (matcher.matches()) { final String opName = matcher.group(1); if (!operators.containsKey(opName)) { final Operator operator = new Operator(); operator.setName(opName); operator.setAlias(matcher.group(2)); parsePattern(operator, matcher.group(3)); operators.put(operator.getName(), operator); operators.put(operator.getAlias(), operator); } } line = bufferedReader.readLine(); } } catch (final IOException e) { throw new IOException("An IOException occured while processing the spec file", e); } } catch (final FileNotFoundException e) { throw e; } return operators; } /** * * @param operator * @param pattern */ private static void parsePattern(final Operator operator, final String pattern) { String temp = pattern; if (pattern.contains("implicit")) { temp = pattern.substring(0, pattern.indexOf("implicit")); operator.setImplicitInformation(pattern.substring(pattern.indexOf("implicit"))); } operator.setPattern(temp); int operatorIndex = 0; if (temp.contains("infixop")) { operator.setOperatorType(OperatorType.INFIXOP); operatorIndex = temp.indexOf("infixop") + "infixop".length(); } else { operator.setOperatorType(OperatorType.OP); operatorIndex = temp.indexOf("op") + "op".length(); } final ArrayList prefixParameters = new ArrayList<>(); final ArrayList postfixParameters = new ArrayList<>(); final ArrayList argumentDelimiters = new ArrayList<>(); int paramIndex = temp.indexOf("_", 0); while (paramIndex != -1 && paramIndex < operatorIndex) { prefixParameters.add(ParameterType.WILDCARD); paramIndex = temp.indexOf("_", paramIndex+1); } operator.setPrefixArguments(prefixParameters); if (temp.contains(BracketType.ROUND.getOpeningBracket())) { operator.setBracketType(BracketType.ROUND); } else if (temp.contains(BracketType.SQUARED.getOpeningBracket())) { operator.setBracketType(BracketType.SQUARED); } else { operator.setBracketType(BracketType.NONE); if (operator.getOperatorType().equals(OperatorType.OP)) { operator.setPostfixArguments(postfixParameters); return; } } temp = temp.substring(operatorIndex, temp.length()).trim(); final Matcher argumentMatcher = ARGUMENT_PATTERN.matcher(temp); while(argumentMatcher.find()) { final String subString = argumentMatcher.group(0); for (final ParameterType type : ParameterType.values()) { if (subString.equals(type.getText())) { postfixParameters.add(type); } } for (final Delimiter delimiter : Delimiter.values()) { if (subString.equals(delimiter.getText())) { argumentDelimiters.add(delimiter); } } } operator.setPostfixArguments(postfixParameters); operator.setArgumentDelimiters(argumentDelimiters); } }