package de.gaalop.clucalc.input; import de.gaalop.CodeParser; import de.gaalop.CodeParserException; import de.gaalop.InputFile; import de.gaalop.cfg.ControlFlowGraph; import java.io.BufferedReader; import java.io.IOException; import java.io.StringReader; import java.util.Arrays; import java.util.LinkedList; import org.antlr.v4.runtime.ANTLRInputStream; import org.antlr.v4.runtime.CommonTokenStream; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * This class wraps the ANTLR parsers inside the Gaalop CodeGenerator interface. * It is implemented as a singleton because it does not have any state. */ public enum CluCalcCodeParser implements CodeParser { INSTANCE; // static in order not to get an "illegal reference to static field from initializer" error private static final Log log = LogFactory.getLog(CluCalcCodeParser.class); private Plugin plugin; public void setPluginReference(Plugin plugin) { if (this.plugin == null) { this.plugin = plugin; } } @Override public ControlFlowGraph parseFile(InputFile input) throws CodeParserException { log.debug("Processing " + input.getName() + ", Content: \n" + input.getContent()); ControlFlowGraph graph; try { graph = parse(input); } catch (Throwable e) { throw new CodeParserException(input, e.getMessage(), e); } graph.setSource(input); return graph; } private ControlFlowGraph parse(InputFile input) throws CodeParserException, IOException { LinkedList<String> onlyEvaluates = new LinkedList<String>(); LinkedList<String> outputs = new LinkedList<String>(); String content = input.getContent(); BufferedReader reader = new BufferedReader(new StringReader(content)); String line = null; StringBuilder builder = new StringBuilder(); while ((line = reader.readLine()) != null) { if (line.trim().startsWith("//#pragma")) { String line2 = line.replaceAll("\t", " "); while (line2.contains(" ")) line2 = line2.replaceAll(" "," "); String whichPragma = line2.substring(10,line2.indexOf(" ",10)); if (whichPragma.equals("range") || whichPragma.equals("unroll") || whichPragma.equals("count")) { builder.append(line); builder.append("\n"); } else { //process here String rest = line2.substring(line2.indexOf(" ",10)+1); if (whichPragma.equals("output")) { //IDENTIFIER blade+ String[] parts = rest.split(" "); for (int i=1;i<parts.length;i++) outputs.add(parts[0]+" "+parts[i]); } else { if (whichPragma.equals("onlyEvaluate")) { //IDENTIFIER+ String[] parts = rest.split(" "); onlyEvaluates.addAll(Arrays.asList(parts)); } else throw new CodeParserException(input, "pragma "+whichPragma+" is unknown."); } } } else { builder.append(line); builder.append("\n"); } } String program = builder.toString(); ANTLRInputStream inputStream = new ANTLRInputStream(new StringReader(program)); CluCalcLexer lexer = new CluCalcLexer(inputStream); CommonTokenStream tokenStream = new CommonTokenStream(lexer); CluCalcParser parser = new CluCalcParser(tokenStream); CluVisitor visitor = new CluVisitor(); visitor.visit(parser.script()); ControlFlowGraph graph = visitor.graph; for (String output: outputs) graph.getPragmaOutputVariables().add(output); for (String onlyEval: onlyEvaluates) graph.getPragmaOnlyEvaluateVariables().add(onlyEval); return graph; } }