| summaryrefslogtreecommitdiff |
diff options
| author | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2018-05-25 07:40:11 +0200 |
|---|---|---|
| committer | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2018-05-25 07:40:11 +0200 |
| commit | f7d1dab52196f0d4fb0932b321645cf91e95877e (patch) | |
| tree | 8ea0a0b19ac8d1da4011824538d305af28895d7f | |
Isolates Tabellion's "ast-to-instr" module.
28 files changed, 5486 insertions, 0 deletions
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..49f6b10 --- /dev/null +++ b/Makefile @@ -0,0 +1,70 @@ +## Parameters ################################################################## +SRC_DIR ?= ${CURDIR}/src/ +BIN_DIR ?= ${CURDIR}/bin/ +LIB_DIR ?= ${CURDIR}/lib/ + +TARGET ?= ghdl2hastabel.jar +INSTALL_DIR ?= $(LIB_DIR) + +#### Where to get the missing Jar files. +JAR_SOURCE ?= "https://noot-noot.org/tabellion/jar/" + +#### Binaries +###### JAR binary +JAR ?= jar + +###### JRE binary +JAVA ?= java + +###### JDK binary +JAVAC ?= javac + +##### Downloader +DOWNLOADER ?= wget + +## Parameters Sanity Check ##################################################### +ifeq ($(strip $(JAVA)),) +$(error No Java executable defined as parameter.) +endif + +ifeq ($(strip $(JAVAC)),) +$(error No Java compiler defined as parameter.) +endif + +## Java Config ################################################################# +CLASSPATH = "$(SRC_DIR):$(BIN_DIR)" + +## Makefile Magic ############################################################## +JAVA_SOURCES = \ + $(wildcard $(SRC_DIR)/ghdl2hastabel/*.java) \ + $(wildcard $(SRC_DIR)/ghdl2hastabel/*/*.java) +CLASSES = $(patsubst $(SRC_DIR)/%,$(BIN_DIR)/%, $(JAVA_SOURCES:.java=.class)) + +## Makefile Rules ############################################################## +$(TARGET): $(JAVA_SOURCES) $(CLASSES) + $(MAKE) $(LIB_DIR) + rm -f $(TARGET) $(INSTALL_DIR)/$@ + $(JAR) cf $@ -C $(BIN_DIR) . + cp $@ $(INSTALL_DIR)/$@ + +clean: + rm -rf $(BIN_DIR)/* + rm -f $(TARGET) + +$(CLASSES): $(BIN_DIR)/%.class: $(SRC_DIR)/%.java $(BIN_DIR) + $(JAVAC) -cp $(CLASSPATH) -d $(BIN_DIR) $< + +%.jar: + $(MAKE) $(LIB_DIR) + echo "Attempting to download missing jar '$@'..." + cd $(LIB_DIR); $(DOWNLOADER) "$(JAR_SOURCE)/$(notdir $@)" + +$(LIB_DIR): + mkdir -p $@ + +$(BIN_DIR): + mkdir -p $@ + +##### For my private use... +publish: $(TARGET) + scp $< dreamhost:~/noot-noot/tabellion/jar/ diff --git a/src/ghdl2hastabel/Depths.java b/src/ghdl2hastabel/Depths.java new file mode 100644 index 0000000..3e01423 --- /dev/null +++ b/src/ghdl2hastabel/Depths.java @@ -0,0 +1,77 @@ +package ghdl2hastabel; + +import java.util.Map; +import java.util.HashMap; + +public class Depths +{ + private static final Map<Integer, IDs> TO_ID; + private static final OutputFile DEPTHS_OUTPUT; + private static int highest_depth; + + static + { + highest_depth = -1; + + TO_ID = new HashMap<Integer, IDs>(); + + /* TODO: filename as a param? */ + DEPTHS_OUTPUT = OutputFile.new_output_file("depths.mod"); + } + + private Depths () {} /* Utility class. */ + + public static IDs get_id_from_depth + ( + final String depth + ) + { + return get_id_from_depth(Integer.valueOf(depth)); + } + + public static IDs get_id_from_depth + ( + final Integer depth + ) + { + IDs result; + + result = TO_ID.get(depth); + + if (result == null) + { + result = IDs.generate_new_id(DEPTHS_OUTPUT, "depth"); + + TO_ID.put(depth, result); + } + + if (depth.intValue() > highest_depth) + { + highest_depth = depth.intValue(); + } + + return result; + } + + public static void generate_predicates () + { + for + ( + int current_depth = highest_depth; + current_depth > 0; + --current_depth + ) + { + for (int i = 0; i < current_depth; ++i) + { + Predicates.add_entry + ( + DEPTHS_OUTPUT, + "is_lower_than", + get_id_from_depth(new Integer(i)), + get_id_from_depth(new Integer(current_depth)) + ); + } + } + } +} diff --git a/src/ghdl2hastabel/Expressions.java b/src/ghdl2hastabel/Expressions.java new file mode 100644 index 0000000..3c8f547 --- /dev/null +++ b/src/ghdl2hastabel/Expressions.java @@ -0,0 +1,430 @@ +package ghdl2hastabel; + +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.HashMap; + +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpression; +import javax.xml.xpath.XPathExpressionException; + +public class Expressions +{ + private static final XPathExpression XPE_GET_LEFT_SIDE; + private static final XPathExpression XPE_GET_RIGHT_SIDE; + private static final XPathExpression XPE_GET_OPERAND; + private static final XPathExpression XPE_GET_FUN_PARAMETERS; + private static final XPathExpression XPE_GET_INDEX_LIST; + private static final XPathExpression XPE_GET_NAMED_ENTITY; + private static final XPathExpression XPE_GET_PREFIX_NAMED_ENTITY; + private static final XPathExpression XPE_GET_PREFIX; + + static + { + XPE_GET_LEFT_SIDE = XMLManager.compile_or_die("./left"); + XPE_GET_RIGHT_SIDE = XMLManager.compile_or_die("./right"); + XPE_GET_OPERAND = XMLManager.compile_or_die("./operand"); + + XPE_GET_FUN_PARAMETERS = + XMLManager.compile_or_die + ( + "./parameter_association_chain/el/actual" + ); + + XPE_GET_INDEX_LIST = XMLManager.compile_or_die("./index_list/el"); + + XPE_GET_NAMED_ENTITY = XMLManager.compile_or_die("./named_entity"); + XPE_GET_PREFIX_NAMED_ENTITY = + XMLManager.compile_or_die + ( + "./prefix/named_entity" + ); + + XPE_GET_PREFIX = XMLManager.compile_or_die("./prefix"); + } + + private static enum Operator + { + /* From GHDL's ./src/vhdl/nodes_meta.adb */ + IDENTITY("identity_operator", "+", false), /* assuming it means "+ number" */ + NEGATION("negation_operator", "-", false), /* assuming it means "- number" */ + ABSOLUTE("absolute_operator", "abs", false), + + NOT("not_operator", "not", false), + + CONDITION("condition_operator", "???", true), /* FIXME: what's this? */ + + /* Flattens vectors using an operator. */ + REDUCTION_AND("reduction_and_operator", "and", false), + REDUCTION_OR("reduction_or_operator", "or", false), + REDUCTION_NAND("reduction_nand_operator", "nand", false), + REDUCTION_NOR("reduction_nor_operator", "nor", false), + REDUCTION_XOR("reduction_xor_operator", "xor", false), + REDUCTION_XNOR("reduction_xnor_operator", "xnor", false), + + AND("and_operator", "and", true), + OR("or_operator", "or", true), + NAND("nand_operator", "nand", true), + NOR("nor_operator", "nor", true), + XOR("xor_operator", "xor", true), + XNOR("xnor_operator", "xnor", true), + + EQUALITY("equality_operator", "=", true), + INEQUALITY("inequality_operator", "/=", true), + LESS_THAN("less_than_operator", "<", true), + LESS_THAN_OR_EQUAL("less_than_or_equal_operator", "<=", true), + GREATER_THAN("greater_than_operator", ">", true), + GREATER_THAN_OR_EQUAL("greater_than_or_equal_operator", ">=", true), + + /* FIXME: What are those? */ + MATCH_EQUALITY("match_equality_operator", "???", true), + MATCH_INEQUALITY("match_inequality_operator", "???", true), + MATCH_LESS_THAN("match_less_than_operator", "???", true), + MATCH_LESS_THAN_OR_EQUAL + ( + "match_less_than_or_equal_operator", + "???", + true + ), + MATCH_GREATER_THAN("match_greater_than_operator", "???", true), + MATCH_GREATER_THAN_OR_EQUAL + ( + "match_greater_than_or_equal_operator", + "???", + true + ), + + /* Called using "logical array OP integer", apparently. */ + SLL("sll_operator", "sll", true), + SLA("sla_operator", "sla", true), + SRL("srl_operator", "srl", true), + SRA("sra_operator", "sra", true), + ROL("rol_operator", "rol", true), + ROR("ror_operator", "ror", true), + + ADDITION("addition_operator", "+", true), + SUBSTRACTION("substraction_operator", "-", true), + CONCATENATION("concatenation_operator", "&", true), + MULTIPLICATION("multiplication_operator", "*", true), + DIVISION("division_operator", "/", true), + MODULUS("modulus_operator", "mod", true), + REMAINDER("remainder_operator", "rem", true), + EXPONENTIATION("exponentiation_operator", "**", true); + + /** Static **************************************************************/ + private static final Map<String, Operator> FROM_TAG; + + static + { + final Operator operators[]; + + FROM_TAG = new HashMap<String, Operator>(); + + operators = Operator.class.getEnumConstants(); /* We Java now... */ + + for (final Operator op: operators) + { + FROM_TAG.put(op.tag, op); + } + } + + /** Non-Static **********************************************************/ + private final String tag; + private final String symbol; + private final boolean is_binary; + + private Operator + ( + final String tag, + final String symbol, + final boolean is_binary + ) + { + this.tag = tag; + this.symbol = symbol; + this.is_binary = is_binary; + } + } + + public static void process + ( + final List<IDs> elements, + final StringBuilder structure, + final Node current_node + ) + throws XPathExpressionException + { + final String kind; + final Operator op; + + kind = XMLManager.get_attribute(current_node, "kind"); + + op = Operator.FROM_TAG.get(kind); + + if (op == null) + { + process_non_operator(elements, structure, current_node, kind); + } + else if (op.is_binary) + { + structure.append("(?"); + elements.add + ( + Strings.get_id_from_string + ( + op.symbol + ) + ); + + process + ( + elements, + structure, + (Node) XPE_GET_LEFT_SIDE.evaluate + ( + current_node, + XPathConstants.NODE + ) + ); + + process + ( + elements, + structure, + (Node) XPE_GET_RIGHT_SIDE.evaluate + ( + current_node, + XPathConstants.NODE + ) + ); + + structure.append(")"); + } + else + { + structure.append("(?"); + elements.add + ( + Strings.get_id_from_string + ( + op.symbol + ) + ); + + process + ( + elements, + structure, + (Node) XPE_GET_OPERAND.evaluate + ( + current_node, + XPathConstants.NODE + ) + ); + + structure.append(")"); + } + } + + public static void process_non_operator + ( + final List<IDs> elements, + final StringBuilder structure, + final Node current_node, + final String kind + ) + throws XPathExpressionException + { + if (kind.equals("simple_name")) + { + final Node named_entity; + + named_entity = + (Node) XPE_GET_NAMED_ENTITY.evaluate + ( + current_node, + XPathConstants.NODE + ); + + structure.append("?"); + + elements.add + ( + Waveforms.get_associated_waveform_id + ( + IDs.get_id_from_xml_id + ( + XMLManager.get_attribute(named_entity, "ref"), + null + ) + ) + ); + } + else if (kind.equals("function_call")) + { + final Node named_entity; + final NodeList params; + final int params_length; + + named_entity = + (Node) XPE_GET_PREFIX/*_NAMED_ENTITY*/.evaluate + ( + current_node, + XPathConstants.NODE + ); + + structure.append("(?"); + + /* + * TODO: Handle functions better, like: + elements.add + ( + IDs.get_id_from_xml_id + ( + XMLManager.get_attribute(named_entity, "ref"), + null + ) + ); + * But for now, we'll just use the function's name as string: + */ + elements.add + ( + Strings.get_id_from_string + ( + XMLManager.get_attribute(named_entity, "identifier") + ) + ); + + + params = + (NodeList) XPE_GET_FUN_PARAMETERS.evaluate + ( + current_node, + XPathConstants.NODESET + ); + + params_length = params.getLength(); + + for (int i = 0; i < params_length; ++i) + { + process + ( + elements, + structure, + params.item(i) + ); + } + + structure.append(")"); + } + else if (kind.equals("indexed_name")) /* vector */ + { + final Node named_entity; + final NodeList params; + final int params_length; + + named_entity = + (Node) XPE_GET_PREFIX_NAMED_ENTITY.evaluate + ( + current_node, + XPathConstants.NODE + ); + + structure.append("(?"); + + elements.add + ( + Waveforms.get_associated_waveform_id + ( + IDs.get_id_from_xml_id + ( + XMLManager.get_attribute(named_entity, "ref"), + null + ) + ) + ); + + params = + (NodeList) XPE_GET_INDEX_LIST.evaluate + ( + current_node, + XPathConstants.NODESET + ); + + params_length = params.getLength(); + + for (int i = 0; i < params_length; ++i) + { + process + ( + elements, + structure, + params.item(i) + ); + } + + structure.append(")"); + } + else if (kind.contains("literal")) + { + /* + grep "Kind.*Literal" ./src/vhdl/nodes_meta.adb | sort | uniq -u + points to: + "character_literal"; + "enumeration_literal"; + "floating_point_literal"; + "integer_literal"; + "null_literal"; + "overflow_literal"; + "physical_fp_literal"; + "physical_int_literal"; + "physical_literal"; (unsure if it can happen) + "string_literal8"; + + They don't all use the same structure, so we're going to handle them + later. + TODO + */ + + structure.append("?"); + elements.add + ( + Strings.get_id_from_string + ( + "l" + ) + ); + + } + else if (kind.contains("attribute")) + { + structure.append("(?"); + + elements.add + ( + Strings.get_id_from_string + ( + /* FIXME: Kind of a hacky */ + kind.replace("_attribute", "") + ) + ); + + process + ( + elements, + structure, + (Node) XPE_GET_PREFIX.evaluate + ( + current_node, + XPathConstants.NODE + ) + ); + + structure.append(")"); + } + } +} diff --git a/src/ghdl2hastabel/Functions.java b/src/ghdl2hastabel/Functions.java new file mode 100644 index 0000000..b854c0d --- /dev/null +++ b/src/ghdl2hastabel/Functions.java @@ -0,0 +1,33 @@ +package ghdl2hastabel; + +public class Functions +{ + public static void add_entry + ( + final String function_name, + final IDs... params + ) + { + add_entry(Main.get_main_output(), function_name, params); + } + + public static void add_entry + ( + final OutputFile output, + final String function_name, + final IDs... params + ) + { + output.write("(set_function "); + + output.write(function_name); + + for (final IDs param: params) + { + output.write(" " + param.get_value()); + } + + output.write(")"); + output.insert_newline(); + } +} diff --git a/src/ghdl2hastabel/IDs.java b/src/ghdl2hastabel/IDs.java new file mode 100644 index 0000000..23bdafb --- /dev/null +++ b/src/ghdl2hastabel/IDs.java @@ -0,0 +1,134 @@ +package ghdl2hastabel; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Map; +import java.util.HashMap; + +public class IDs +{ + /** Static *****************************************************************/ + private static final Map<String, IDs> FROM_XML; + private static final OutputFile XML_MAP_OUTPUT; + private static int next_id; + + static + { + next_id = 0; + + FROM_XML = new HashMap<String, IDs>(); + + /* TODO: filename as a param? */ + XML_MAP_OUTPUT = OutputFile.new_output_file("xml_to_instr.map"); + } + + public static IDs get_id_from_xml_id + ( + final String xml_id, + final String type + ) + { + return + get_id_from_xml_id + ( + Main.get_main_output(), + xml_id, + type + ); + } + + public static IDs get_id_from_xml_id + ( + final OutputFile output, + final String xml_id, + final String type + ) + { + IDs result; + + result = FROM_XML.get(xml_id); + + if (result == null) + { + result = generate_new_id(output, type); + + FROM_XML.put(xml_id, result); + + XML_MAP_OUTPUT.write("(xml->instr "); + XML_MAP_OUTPUT.write(xml_id); + XML_MAP_OUTPUT.write(" "); + XML_MAP_OUTPUT.write(Integer.toString(result.get_value())); + XML_MAP_OUTPUT.write(")"); + XML_MAP_OUTPUT.insert_newline(); + + } + else if ((result.type == null) && (type != null)) + { + /* This allows us to get an ID from a simple reference. */ + result.type = type; + + result.add_to_output(output); + } + + return result; + } + + public static IDs generate_new_id + ( + final String type + ) + { + return generate_new_id(Main.get_main_output(), type); + } + + public static IDs generate_new_id + ( + final OutputFile output, + final String type + ) + { + final IDs result; + + result = new IDs(type); + + if (type != null) + { + result.add_to_output(output); + } + + return result; + } + + /** Non-Static *************************************************************/ + private final int value; + private String type; + + private IDs (final String type) + { + this.type = type; + + value = IDs.next_id; + + IDs.next_id += 1; + } + + public String get_type () + { + return type; + } + + public int get_value () + { + return value; + } + + private void add_to_output (final OutputFile output) + { + output.write("(add_element "); + output.write(type); + output.write(" "); + output.write(Integer.toString(value)); + output.write(")"); + output.insert_newline(); + } +} diff --git a/src/ghdl2hastabel/Main.java b/src/ghdl2hastabel/Main.java new file mode 100644 index 0000000..0850e06 --- /dev/null +++ b/src/ghdl2hastabel/Main.java @@ -0,0 +1,184 @@ +package ghdl2hastabel; + +import ghdl2hastabel.vhdl.File; + +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpression; +import javax.xml.xpath.XPathExpressionException; + +import java.util.Collection; +import java.util.Stack; + +public class Main +{ + private static final XPathExpression XPE_FIND_ALL_VHDL_FILES; + private static Parameters PARAMETERS; + private static Document XML_ROOT; + private static OutputFile MAIN_OUTPUT; + + static + { + XPE_FIND_ALL_VHDL_FILES = + XMLManager.compile_or_die + ( + //"./*/*/el[@kind=\"design_file\"][@file]" + "//el[@kind=\"design_file\"][@file]" + ); + } + + public static void main (final String... args) + { + final Collection<Node> vhdl_files; + + PARAMETERS = new Parameters(args); + + if (!PARAMETERS.are_valid()) + { + return; + } + + try + { + XML_ROOT = XMLManager.get_document(PARAMETERS.get_xml_file()); + } + catch (final Exception e) + { + System.err.println + ( + "[E] Could not load XML file \"" + + PARAMETERS.get_xml_file() + + "\":" + ); + + e.printStackTrace(); + + return; + } + + MAIN_OUTPUT = OutputFile.new_output_file("structural.mod"); + + try + { + vhdl_files = + XMLManager.node_list_to_node_collection + ( + (NodeList) XPE_FIND_ALL_VHDL_FILES.evaluate + ( + XML_ROOT, + XPathConstants.NODESET + ) + ); + } + catch (final XPathExpressionException xpee) + { + System.err.println + ( + "[E] Something went wrong when looking for the VHDL files:" + ); + + xpee.printStackTrace(); + + return; + } + + parse_content(vhdl_files); + + Depths.generate_predicates(); + + OutputFile.close_all(); + } + + private static void parse_content (final Collection<Node> vhdl_files) + { + /* Stack highly recommended over FIFO (you don't want to grow large). */ + final Stack<ParsableXML> waiting_list; + + waiting_list = new Stack<ParsableXML>(); + + for (final Node f: vhdl_files) + { + waiting_list.push(new File(null, f)); + } + + while (!waiting_list.isEmpty()) + { + final Collection<ParsableXML> children; + + try + { + waiting_list.pop().parse(waiting_list); + } + catch (final XPathExpressionException xpee) + { + System.err.println + ( + "[E] Something went wrong while parsing the XML file:" + ); + + xpee.printStackTrace(); + + return; + } + } + } + + public static boolean node_is_function_or_literal (final String xml_id) + throws XPathExpressionException + { + final XPathExpression xpe_find_el_from_id; + final Node n; + final String kind; + + xpe_find_el_from_id = + XMLManager.compile_or_die + ( + ".//el[@id=\"" + + xml_id + + "\"]" + ); + + n = + (Node) xpe_find_el_from_id.evaluate + ( + XML_ROOT, + XPathConstants.NODE + ); + + if (n == (Node) null) + { + return true; + } + + kind = XMLManager.get_attribute(n, "kind"); + + if (kind.equals("function_declaration")) + { + return true; + } + else if (kind.equals("enumeration_literal")) + { + return true; + } + + return false; + } + + public static Document get_xml_root () + { + return XML_ROOT; + } + + public static OutputFile get_main_output () + { + return MAIN_OUTPUT; + } + + public static Parameters get_parameters () + { + return PARAMETERS; + } +} diff --git a/src/ghdl2hastabel/OutputFile.java b/src/ghdl2hastabel/OutputFile.java new file mode 100644 index 0000000..45ef252 --- /dev/null +++ b/src/ghdl2hastabel/OutputFile.java @@ -0,0 +1,137 @@ +package ghdl2hastabel; + +import java.util.ArrayList; +import java.util.Collection; + +import java.io.File; +import java.io.FileWriter; +import java.io.BufferedWriter; + +public class OutputFile +{ + private static Collection<OutputFile> ALL_OUTPUT_FILES; + + static + { + ALL_OUTPUT_FILES = new ArrayList<OutputFile>(); + } + + public static void close_all () + { + for (final OutputFile f: ALL_OUTPUT_FILES) + { + f.close(); + } + } + + public static OutputFile new_output_file (final String filename) + { + final OutputFile result; + + result = + new OutputFile + ( + Main.get_parameters().get_output_directory() + + "/" + + filename + ); + + ALL_OUTPUT_FILES.add(result); + + return result; + } + + /** Non-Static *************************************************************/ + private final String filename; + private final BufferedWriter buffered_writer; + + private OutputFile (final String filename) + { + BufferedWriter bf; + + this.filename = filename; + + try + { + bf = new BufferedWriter(new FileWriter(new File(filename))); + } + catch (final Exception e) + { + bf = null; + + System.err.println + ( + "[F] Could not create new output file \"" + + filename + + "\":" + ); + + e.printStackTrace(); + + System.exit(-1); + } + + buffered_writer = bf; + } + + public void write (final String data) + { + try + { + buffered_writer.write(data); + } + catch (final Exception e) + { + System.err.println + ( + "[F] Could not write to output file \"" + + filename + + "\":" + ); + + e.printStackTrace(); + + System.exit(-1); + } + } + + public void insert_newline () + { + try + { + buffered_writer.newLine(); + } + catch (final Exception e) + { + System.err.println + ( + "[F] Could not write to output file \"" + + filename + + "\":" + ); + + e.printStackTrace(); + + System.exit(-1); + } + } + + private void close () + { + try + { + buffered_writer.close(); + } + catch (final Exception e) + { + System.err.println + ( + "[E] Could not properly close output file \"" + + filename + + "\":" + ); + + e.printStackTrace(); + } + } +} diff --git a/src/ghdl2hastabel/Parameters.java b/src/ghdl2hastabel/Parameters.java new file mode 100644 index 0000000..522ffb4 --- /dev/null +++ b/src/ghdl2hastabel/Parameters.java @@ -0,0 +1,59 @@ +package ghdl2hastabel; + +import java.util.List; +import java.util.ArrayList; + +public class Parameters +{ + private final String xml_file; + private final String output_dir; + + private final boolean are_valid; + + public static void print_usage () + { + System.out.println + ( + "AST-to-Instr\n" + + "USAGE:\n" + + "\tjava Main <XML_FILE> <OUTPUT_DIR>\n" + + "PARAMETERS:\n" + + "\t- <XML_FILE>\tThe AST (XML format).\n" + + "\t- <OUTPUT_DIR>\tThe output directory (must already exist)." + ); + } + + public Parameters (String... args) + { + if (args.length != 2) + { + print_usage(); + + xml_file = new String(); + output_dir = new String(); + are_valid = false; + + return; + } + + xml_file = args[0]; + output_dir = args[1]; + + are_valid = true; + } + + public String get_xml_file () + { + return xml_file; + } + + public String get_output_directory () + { + return output_dir; + } + + public boolean are_valid () + { + return are_valid; + } +} diff --git a/src/ghdl2hastabel/ParsableXML.java b/src/ghdl2hastabel/ParsableXML.java new file mode 100644 index 0000000..f5cf29b --- /dev/null +++ b/src/ghdl2hastabel/ParsableXML.java @@ -0,0 +1,32 @@ +package ghdl2hastabel; + +import org.w3c.dom.Node; + +import java.util.Stack; + +import javax.xml.xpath.XPathExpressionException; + +public abstract class ParsableXML +{ + protected final IDs parent_id; + protected final Node xml_node; + + public ParsableXML + ( + final IDs parent_id, + final Node xml_node + ) + { + this.parent_id = parent_id; + this.xml_node = xml_node; + } + + public void parse + ( + final Stack<ParsableXML> waiting_list + ) + throws XPathExpressionException + { + + } +} diff --git a/src/ghdl2hastabel/Predicates.java b/src/ghdl2hastabel/Predicates.java new file mode 100644 index 0000000..3b14e7c --- /dev/null +++ b/src/ghdl2hastabel/Predicates.java @@ -0,0 +1,33 @@ +package ghdl2hastabel; + +public class Predicates +{ + public static void add_entry + ( + final String predicate_name, + final IDs... params + ) + { + add_entry(Main.get_main_output(), predicate_name, params); + } + + public static void add_entry + ( + final OutputFile output, + final String predicate_name, + final IDs... params + ) + { + output.write("("); + + output.write(predicate_name); + + for (final IDs param: params) + { + output.write(" " + param.get_value()); + } + + output.write(")"); + output.insert_newline(); + } +} diff --git a/src/ghdl2hastabel/Strings.java b/src/ghdl2hastabel/Strings.java new file mode 100644 index 0000000..68e17e9 --- /dev/null +++ b/src/ghdl2hastabel/Strings.java @@ -0,0 +1,56 @@ +package ghdl2hastabel; + +import java.util.Map; +import java.util.HashMap; + +public class Strings +{ + private static final Map<String, IDs> TO_ID; + private static final OutputFile STRING_MAP_OUTPUT; + + static + { + TO_ID = new HashMap<String, IDs>(); + + /* TODO: filename as a param? */ + STRING_MAP_OUTPUT = OutputFile.new_output_file("string_to_instr.map"); + } + + private Strings () {} /* Utility class. */ + + public static IDs get_id_from_string + ( + final String string + ) + { + return get_id_from_string(Main.get_main_output(), string); + } + + public static IDs get_id_from_string + ( + final OutputFile output, + String string + ) + { + IDs result; + + string = string.toLowerCase(); + result = TO_ID.get(string); + + if (result == null) + { + result = IDs.generate_new_id(output, "string"); + + TO_ID.put(string, result); + + STRING_MAP_OUTPUT.write("(string->instr \""); + STRING_MAP_OUTPUT.write(string); + STRING_MAP_OUTPUT.write("\" "); + STRING_MAP_OUTPUT.write(Integer.toString(result.get_value())); + STRING_MAP_OUTPUT.write(")"); + STRING_MAP_OUTPUT.insert_newline(); + } + + return result; + } +} diff --git a/src/ghdl2hastabel/Waveforms.java b/src/ghdl2hastabel/Waveforms.java new file mode 100644 index 0000000..682541c --- /dev/null +++ b/src/ghdl2hastabel/Waveforms.java @@ -0,0 +1,32 @@ +package ghdl2hastabel; + +import java.util.Map; +import java.util.HashMap; + +public class Waveforms +{ + private static final Map<IDs, IDs> TO_WAVEFORM; + + static + { + TO_WAVEFORM = new HashMap<IDs, IDs>(); + } + + private Waveforms () {} /* Utility class. */ + + public static IDs get_associated_waveform_id (final IDs source) + { + IDs result; + + result = TO_WAVEFORM.get(source); + + if (result == null) + { + result = IDs.generate_new_id("waveform"); + + TO_WAVEFORM.put(source, result); + } + + return result; + } +} diff --git a/src/ghdl2hastabel/XMLManager.java b/src/ghdl2hastabel/XMLManager.java new file mode 100644 index 0000000..f12c990 --- /dev/null +++ b/src/ghdl2hastabel/XMLManager.java @@ -0,0 +1,128 @@ +package ghdl2hastabel; + +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import org.xml.sax.SAXException; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.ParserConfigurationException; + +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathExpression; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; + +import java.io.File; +import java.io.IOException; + +import java.util.ArrayList; +import java.util.Collection; + +public class XMLManager +{ + /* ... */ + /* private static final DocumentBuilderFactoryCreatorMakerInstanciator; */ + /* private static final DocumentBuilderFactoryCreatorMaker; */ + /* private static final DocumentBuilderFactoryCreator; */ + private static final DocumentBuilderFactory DOC_BUILDER_FACTORY; + private static final DocumentBuilder DOC_BUILDER; + + private static final XPathFactory XPATH_FACTORY; + private static final XPath XPATH; + + static + { + DocumentBuilder i_dont_even; + + DOC_BUILDER_FACTORY = DocumentBuilderFactory.newInstance(); + + try + { + i_dont_even = DOC_BUILDER_FACTORY.newDocumentBuilder(); + } + catch (final Exception e) + { + i_dont_even = null; + + System.err.println + ( + "[E] Err... You somehow managed to trigger an exception from purely" + + " static members:" + ); + + e.printStackTrace(); + + System.exit(-1); + } + + DOC_BUILDER = i_dont_even; + + XPATH_FACTORY = XPathFactory.newInstance(); + XPATH = XPATH_FACTORY.newXPath(); + } + + private XMLManager () {} /* Utility Class. */ + + public static Document get_document (final String filename) + throws + SAXException, + IOException + { + final File file; + + file = new File(filename); + + return DOC_BUILDER.parse(file); + } + + public static XPathExpression compile (final String expression) + throws XPathExpressionException + { + return XPATH.compile(expression); + } + + public static XPathExpression compile_or_die (final String expression) + { + try + { + return XPATH.compile(expression); + } + catch (final XPathExpressionException xpee) + { + System.err.println("[P] Invalid XPathExpression (report as bug):"); + xpee.printStackTrace(); + + System.exit(-1); + } + + return null; /* Because Java. */ + } + + public static Collection<Node> node_list_to_node_collection + ( + final NodeList nl + ) + { + final Collection<Node> result; + final int nl_length; + + result = new ArrayList<Node>(); + + nl_length = nl.getLength(); + + for (int i = 0; i < nl_length; ++i) + { + result.add(nl.item(i)); + } + + return result; + } + + public static String get_attribute (final Node n, final String attr) + { + return n.getAttributes().getNamedItem(attr).getNodeValue(); + } +} diff --git a/src/ghdl2hastabel/vhdl/.Node.java.swp b/src/ghdl2hastabel/vhdl/.Node.java.swp Binary files differnew file mode 100644 index 0000000..942ae52 --- /dev/null +++ b/src/ghdl2hastabel/vhdl/.Node.java.swp diff --git a/src/ghdl2hastabel/vhdl/Architecture.java b/src/ghdl2hastabel/vhdl/Architecture.java new file mode 100644 index 0000000..36a6819 --- /dev/null +++ b/src/ghdl2hastabel/vhdl/Architecture.java @@ -0,0 +1,351 @@ +package ghdl2hastabel.vhdl; + +import ghdl2hastabel.Functions; +import ghdl2hastabel.Predicates; +import ghdl2hastabel.Strings; +import ghdl2hastabel.ParsableXML; +import ghdl2hastabel.XMLManager; +import ghdl2hastabel.IDs; + +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpression; +import javax.xml.xpath.XPathExpressionException; + +import java.util.Stack; + +public class Architecture extends ParsableXML +{ + private static final XPathExpression XPE_FIND_ENTITY_NAME; + private static final XPathExpression XPE_FIND_SIGNALS; + private static final XPathExpression XPE_FIND_PROCESSES; + private static final XPathExpression XPE_FIND_COMPONENTS; + + static + { + XPE_FIND_ENTITY_NAME = + XMLManager.compile_or_die + ( + "./entity_name/named_entity" + ); + + XPE_FIND_SIGNALS = + XMLManager.compile_or_die + ( + "./*/el[@kind=\"signal_declaration\"]" + ); + + XPE_FIND_PROCESSES = + XMLManager.compile_or_die + ( + "./*/el[@kind=\"sensitized_process_statement\"]" + ); + + XPE_FIND_COMPONENTS = + XMLManager.compile_or_die + ( + "./*/el[@kind=\"component_instantiation_statement\"]" + ); + } + + public Architecture + ( + final IDs parent_id, + final Node xml_node + ) + { + super(parent_id, xml_node); + } + + @Override + public void parse + ( + final Stack<ParsableXML> waiting_list + ) + throws XPathExpressionException + { + final String xml_id; + final IDs local_id; + + xml_id = XMLManager.get_attribute(xml_node, "id"); + + local_id = IDs.get_id_from_xml_id(xml_id, "architecture"); + + /** Parent **************************************************************/ + handle_link_to_file(local_id); + handle_link_to_entity(local_id); + + /** Functions ***********************************************************/ + handle_function_line(local_id); + handle_function_column(local_id); + handle_function_identifier(local_id); + + /** Predicates **********************************************************/ + handle_predicate_has_foreign_flag(local_id); + handle_predicate_has_visible_flag(local_id); + handle_predicate_is_withing_flag(local_id); + handle_predicate_end_has_reserved_id(local_id); + handle_predicate_end_has_identifier(local_id); + + /** Children ************************************************************/ + handle_child_signals(local_id, waiting_list); + handle_child_processes(local_id, waiting_list); + handle_child_components(local_id, waiting_list); + } + + /***************************************************************************/ + /** Parents ****************************************************************/ + /***************************************************************************/ + private void handle_link_to_file + ( + final IDs local_id + ) + { + Predicates.add_entry("is_in_file", local_id, parent_id); + } + + private void handle_link_to_entity + ( + final IDs local_id + ) + throws XPathExpressionException + { + final Node entity_name; + + entity_name = + (Node) XPE_FIND_ENTITY_NAME.evaluate + ( + xml_node, + XPathConstants.NODE + ); + + if (entity_name == (Node) null) + { + System.err.println + ( + "[W] Could not find entity the associated with architecture " + + local_id + + " (XML ID: " + + XMLManager.get_attribute(xml_node, "id") + + ")." + ); + + return; + } + + Predicates.add_entry + ( + "is_architecture_of", + local_id, + IDs.get_id_from_xml_id + ( + XMLManager.get_attribute(entity_name, "ref"), + "entity" + ) + ); + } + + + /***************************************************************************/ + /** Functions **************************************************************/ + /***************************************************************************/ + private void handle_function_line + ( + final IDs local_id + ) + { + Functions.add_entry + ( + "line", + local_id, + Strings.get_id_from_string + ( + XMLManager.get_attribute(xml_node, "line") + ) + ); + } + + private void handle_function_column + ( + final IDs local_id + ) + { + Functions.add_entry + ( + "column", + local_id, + Strings.get_id_from_string + ( + XMLManager.get_attribute(xml_node, "col") + ) + ); + } + + private void handle_function_identifier + ( + final IDs local_id + ) + { + Functions.add_entry + ( + "identifier", + local_id, + Strings.get_id_from_string + ( + XMLManager.get_attribute(xml_node, "identifier") + ) + ); + } + + /***************************************************************************/ + /** Predicates *************************************************************/ + /***************************************************************************/ + private void handle_predicate_has_foreign_flag + ( + final IDs local_id + ) + { + if (XMLManager.get_attribute(xml_node, "foreign_flag").equals("true")) + { + Predicates.add_entry("has_foreign_flag", local_id); + } + } + + private void handle_predicate_has_visible_flag + ( + final IDs local_id + ) + { + if (XMLManager.get_attribute(xml_node, "visible_flag").equals("true")) + { + Predicates.add_entry("has_visible_flag", local_id); + } + } + + private void handle_predicate_is_withing_flag + ( + final IDs local_id + ) + { + if (XMLManager.get_attribute(xml_node, "is_within_flag").equals("true")) + { + Predicates.add_entry("is_within_flag", local_id); + } + } + + private void handle_predicate_end_has_reserved_id + ( + final IDs local_id + ) + { + if + ( + XMLManager.get_attribute + ( + xml_node, + "end_has_reserved_id" + ).equals("true") + ) + { + Predicates.add_entry("end_has_reserved_id", local_id); + } + } + + private void handle_predicate_end_has_identifier + ( + final IDs local_id + ) + { + if + ( + XMLManager.get_attribute + ( + xml_node, + "end_has_identifier" + ).equals("true") + ) + { + Predicates.add_entry("end_has_identifier", local_id); + } + } + + /***************************************************************************/ + /** Children ***************************************************************/ + /***************************************************************************/ + private void handle_child_signals + ( + final IDs local_id, + final Stack<ParsableXML> waiting_list + ) + throws XPathExpressionException + { + final NodeList signals; + final int children_count; + + signals = + (NodeList) XPE_FIND_SIGNALS.evaluate + ( + xml_node, + XPathConstants.NODESET + ); + + children_count = signals.getLength(); + + for (int i = 0; i < children_count; ++i) + { + waiting_list.push(new Signal(local_id, signals.item(i))); + } + } + + private void handle_child_processes + ( + final IDs local_id, + final Stack<ParsableXML> waiting_list + ) + throws XPathExpressionException + { + final NodeList processes; + final int children_count; + + processes = + (NodeList) XPE_FIND_PROCESSES.evaluate + ( + xml_node, + XPathConstants.NODESET + ); + + children_count = processes.getLength(); + + for (int i = 0; i < children_count; ++i) + { + waiting_list.push(new Process(local_id, processes.item(i))); + } + } + + private void handle_child_components + ( + final IDs local_id, + final Stack<ParsableXML> waiting_list + ) + throws XPathExpressionException + { + final NodeList components; + final int children_count; + + components = + (NodeList) XPE_FIND_COMPONENTS.evaluate + ( + xml_node, + XPathConstants.NODESET + ); + + children_count = components.getLength(); + + for (int i = 0; i < children_count; ++i) + { + waiting_list.push(new Component(local_id, components.item(i))); + } + } +} diff --git a/src/ghdl2hastabel/vhdl/CSNode.java b/src/ghdl2hastabel/vhdl/CSNode.java new file mode 100644 index 0000000..bb36824 --- /dev/null +++ b/src/ghdl2hastabel/vhdl/CSNode.java @@ -0,0 +1,309 @@ +package ghdl2hastabel.vhdl; + +import ghdl2hastabel.Depths; +import ghdl2hastabel.OutputFile; +import ghdl2hastabel.Strings; +import ghdl2hastabel.Functions; +import ghdl2hastabel.Predicates; +import ghdl2hastabel.ParsableXML; +import ghdl2hastabel.XMLManager; +import ghdl2hastabel.IDs; + +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpression; +import javax.xml.xpath.XPathExpressionException; + +import java.util.Stack; + +/* Case Statement Node */ +public class CSNode extends ghdl2hastabel.vhdl.Node +{ + private static final XPathExpression XPE_FIND_SOURCES; + private static final XPathExpression XPE_FIND_OTHERS_BRANCH; + private static final XPathExpression XPE_FIND_WHEN_BRANCHES; + + static + { + XPE_FIND_SOURCES = + XMLManager.compile_or_die + ( + "./expression"/*//named_entity"*/ + ); + + XPE_FIND_OTHERS_BRANCH = + XMLManager.compile_or_die + ( + "./case_statement_alternative_chain/el[@kind=\"choice_by_others\"]" + ); + + XPE_FIND_WHEN_BRANCHES = + XMLManager.compile_or_die + ( + "./case_statement_alternative_chain/el" + + "[@kind=\"choice_by_expression\"]" + ); + } + + public CSNode + ( + final OutputFile output, + final IDs parent_id, + final Node xml_node, + final IDs next_node, + final int depth, + final String[] attributes + ) + { + super + ( + output, + parent_id, + xml_node, + next_node, + depth, + attributes + ); + } + + @Override + public void parse + ( + final Stack<ParsableXML> waiting_list + ) + throws XPathExpressionException + { + final String xml_id; + final IDs local_id; + + xml_id = XMLManager.get_attribute(xml_node, "id"); + + local_id = IDs.get_id_from_xml_id(output, xml_id, "node"); + + /** Functions ***********************************************************/ + handle_function_label(local_id); + handle_function_kind(local_id); + handle_function_depth(local_id); + + /** Predicates **********************************************************/ + handle_predicate_has_option(local_id); + handle_predicate_expr_reads(local_id); + + /** Children ************************************************************/ + handle_when_branches(local_id, waiting_list); + handle_others_branch(local_id, waiting_list); + } + + /***************************************************************************/ + /** Functions **************************************************************/ + /***************************************************************************/ + private void handle_function_label + ( + final IDs local_id + ) + { + Functions.add_entry + ( + output, + "label", + local_id, + Strings.get_id_from_string + ( + output, + XMLManager.get_attribute(xml_node, "label") + ) + ); + } + + private void handle_function_kind + ( + final IDs local_id + ) + { + Functions.add_entry + ( + output, + "kind", + local_id, + Strings.get_id_from_string("case") + ); + } + + private void handle_function_depth + ( + final IDs local_id + ) + { + Functions.add_entry + ( + output, + "depth", + local_id, + Depths.get_id_from_depth(new Integer(depth)) + ); + } + + /***************************************************************************/ + /** Predicates *************************************************************/ + /***************************************************************************/ + private void handle_predicate_has_option + ( + final IDs local_id + ) + { + for (final String s: attributes) + { + Predicates.add_entry + ( + output, + "has_option", + local_id, + Strings.get_id_from_string(s) + ); + } + } + + private void handle_predicate_expr_reads + ( + final IDs local_id + ) + throws XPathExpressionException + { + final Node sources; + + sources = + (Node) XPE_FIND_SOURCES.evaluate + ( + xml_node, + XPathConstants.NODE + ); + + handle_read_expr_predicates(local_id, sources); + } + + /***************************************************************************/ + /** Children ***************************************************************/ + /***************************************************************************/ + private void handle_when_branches + ( + final IDs local_id, + final Stack<ParsableXML> waiting_list + ) + throws XPathExpressionException + { + final NodeList when_branches; + final int when_branches_length; + + when_branches = + (NodeList) XPE_FIND_WHEN_BRANCHES.evaluate + ( + xml_node, + XPathConstants.NODESET + ); + + when_branches_length = when_branches.getLength(); + + for (int i = 0; i < when_branches_length; ++i) + { + final Node child; + final String child_xml_id; + final IDs child_local_id; + + child = when_branches.item(i); + child_xml_id = XMLManager.get_attribute(child, "id"); + child_local_id = IDs.get_id_from_xml_id(output, child_xml_id, "node"); + + Predicates.add_entry + ( + output, + "node_connect", + local_id, + child_local_id + ); + + waiting_list.add + ( + new WNode + ( + output, + parent_id, + when_branches.item(i), + next_node, + (depth + 1), + new String[0] + ) + ); + } + } + + private void handle_others_branch + ( + final IDs local_id, + final Stack<ParsableXML> waiting_list + ) + throws XPathExpressionException + { + final Node others_branch; + + others_branch = + (Node) XPE_FIND_OTHERS_BRANCH.evaluate + ( + xml_node, + XPathConstants.NODE + ); + + if (others_branch == (Node) null) + { + if (next_node == (IDs) null) + { + Predicates.add_entry + ( + output, + "is_terminal", + local_id + ); + } + else + { + Predicates.add_entry + ( + output, + "node_connect", + local_id, + next_node + ); + } + } + else + { + final String child_xml_id; + final IDs child_local_id; + + child_xml_id = XMLManager.get_attribute(others_branch, "id"); + child_local_id = IDs.get_id_from_xml_id(output, child_xml_id, "node"); + + Predicates.add_entry + ( + output, + "node_connect", + local_id, + child_local_id + ); + + waiting_list.push + ( + new WNode + ( + output, + parent_id, + others_branch, + next_node, + (depth + 1), + new String[] {"WHEN_OTHERS"} + ) + ); + } + } +} diff --git a/src/ghdl2hastabel/vhdl/Component.java b/src/ghdl2hastabel/vhdl/Component.java new file mode 100644 index 0000000..8c2d4fe --- /dev/null +++ b/src/ghdl2hastabel/vhdl/Component.java @@ -0,0 +1,449 @@ +package ghdl2hastabel.vhdl; + +import ghdl2hastabel.Main; +import ghdl2hastabel.Strings; +import ghdl2hastabel.Waveforms; +import ghdl2hastabel.Functions; +import ghdl2hastabel.Predicates; +import ghdl2hastabel.ParsableXML; +import ghdl2hastabel.XMLManager; +import ghdl2hastabel.IDs; + +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpression; +import javax.xml.xpath.XPathExpressionException; + +import java.util.Stack; + +public class Component extends ParsableXML +{ + private static final XPathExpression XPE_FIND_INST_UNIT; + private static final XPathExpression XPE_FIND_BASE_NAME; + private static final XPathExpression XPE_FIND_ENTITY_NAME; + private static final XPathExpression XPE_FIND_LIBRARY_NAME; + + private static final XPathExpression XPE_FIND_PORT_MAPS; + private static final XPathExpression XPE_FIND_REAL_PORTS; + private static final XPathExpression XPE_FIND_ACTUAL_NE; + private static final XPathExpression XPE_FIND_FORMAL; + + private static final XPathExpression XPE_FIND_GENERIC_MAPS; + + static + { + XPE_FIND_INST_UNIT = XMLManager.compile_or_die("./instantiated_unit"); + XPE_FIND_BASE_NAME = XMLManager.compile_or_die("./base_name"); + + XPE_FIND_ENTITY_NAME = XMLManager.compile_or_die + ( + "./entity_name[@kind=\"selected_name\"]" + ); + + XPE_FIND_LIBRARY_NAME = XMLManager.compile_or_die + ( + "./prefix[@kind=\"simple_name\"]" + ); + + XPE_FIND_PORT_MAPS = + XMLManager.compile_or_die + ( + "./port_map_aspect_chain/el" + + "[@kind=\"association_element_by_expression\"]" + ); + + XPE_FIND_REAL_PORTS = + XMLManager.compile_or_die + ( + "./port_chain/el[@kind=\"interface_signal_declaration\"]" + ); + + XPE_FIND_ACTUAL_NE = XMLManager.compile_or_die("./actual/named_entity"); + XPE_FIND_FORMAL = XMLManager.compile_or_die("./formal"); + + XPE_FIND_GENERIC_MAPS = null; /* TODO */ + } + + public Component + ( + final IDs parent_id, + final Node xml_node + ) + { + super(parent_id, xml_node); + } + + @Override + public void parse + ( + final Stack<ParsableXML> waiting_list + ) + throws XPathExpressionException + { + final String xml_id; + final IDs local_id; + final Node linked_entity; + + xml_id = XMLManager.get_attribute(xml_node, "id"); + + local_id = IDs.get_id_from_xml_id(xml_id, "component"); + + /** Parent **************************************************************/ + handle_link_to_architecture(local_id); + linked_entity = handle_link_to_entity(local_id); + + /** Functions ***********************************************************/ + handle_function_line(local_id); + handle_function_column(local_id); + handle_function_label(local_id); + + /** Predicates **********************************************************/ + + if (linked_entity != (Node) null) + { + handle_predicate_port_maps(local_id, linked_entity); + handle_predicate_generic_maps(local_id, linked_entity); + } + } + + /***************************************************************************/ + /** Parents ****************************************************************/ + /***************************************************************************/ + private void handle_link_to_architecture + ( + final IDs local_id + ) + { + Predicates.add_entry("belongs_to_architecture", local_id, parent_id); + } + + private Node find_entity_from_internal_ref (Node current_node) + throws XPathExpressionException + { + XPathExpression current_query; + + /* + * Get the item containing the reference to the internal description + * of this component. + */ + current_node = + (Node) XPE_FIND_BASE_NAME.evaluate + ( + current_node, + XPathConstants.NODE + ); + + /* Get the referenced component declaration. */ + current_query = + XMLManager.compile_or_die + ( + "./../../declaration_chain/el[@kind=\"component_declaration\"]" + + "[@id=\"" + + XMLManager.get_attribute(current_node, "ref") + + "\"]" + ); + current_node = + (Node) current_query.evaluate + ( + xml_node, + XPathConstants.NODE + ); + + /* Actually get the entity. */ + current_query = + XMLManager.compile_or_die + ( + ".//library_unit[@kind=\"entity_declaration\"][@identifier=\"" + + XMLManager.get_attribute(current_node, "identifier") + + "\"]" + ); + + return + (Node) current_query.evaluate + ( + Main.get_xml_root(), + XPathConstants.NODE + ); + } + + private Node find_entity_from_direct_ref (final Node source_node) + throws XPathExpressionException + { + final XPathExpression xpe_get_matching_entity; + final Node entity_ref, library_ref; + + entity_ref = + (Node) XPE_FIND_ENTITY_NAME.evaluate + ( + source_node, + XPathConstants.NODE + ); + + library_ref = + (Node) XPE_FIND_ENTITY_NAME.evaluate + ( + entity_ref, + XPathConstants.NODE + ); + + xpe_get_matching_entity = + XMLManager.compile_or_die + ( + "./el[@kind=\"library_declaration\"][@identifier=\"" + + XMLManager.get_attribute(library_ref, "identifier") + + "\"]//library_unit[@kind=\"entity_declaration\"][@identifier=\"" + + XMLManager.get_attribute(entity_ref, "identifier") + + "\"]" + ); + + return + (Node) xpe_get_matching_entity.evaluate + ( + Main.get_xml_root(), + XPathConstants.NODE + ); + } + + private Node handle_link_to_entity + ( + final IDs local_id + ) + throws XPathExpressionException + { + final String kind; + Node current_node; + + current_node = + (Node) XPE_FIND_INST_UNIT.evaluate + ( + xml_node, + XPathConstants.NODE + ); + + kind = XMLManager.get_attribute(current_node, "kind"); + + if (kind.equals("simple_name")) + { + current_node = find_entity_from_internal_ref(current_node); + } + else if (kind.equals("entity_aspect_entity")) + { + current_node = find_entity_from_direct_ref(current_node); + } + else + { + System.err.println + ( + "[E] Unsupported component instantiation type for element " + + local_id.get_value() + + " (XML_ID: " + + XMLManager.get_attribute(xml_node, "id") + + ")." + ); + + return null; + } + + if (current_node == (Node) null) + { + System.err.println + ( + "[E] Could not find any entity for the component instantiation " + + local_id.get_value() + + " (XML_ID: " + + XMLManager.get_attribute(xml_node, "id") + + ")." + ); + + return null; + } + + Predicates.add_entry + ( + "is_component_of", + local_id, + IDs.get_id_from_xml_id + ( + XMLManager.get_attribute(current_node, "id"), + "entity" + ) + ); + + return current_node; + } + + /***************************************************************************/ + /** Functions **************************************************************/ + /***************************************************************************/ + private void handle_function_line + ( + final IDs local_id + ) + { + Functions.add_entry + ( + "line", + local_id, + Strings.get_id_from_string + ( + XMLManager.get_attribute(xml_node, "line") + ) + ); + } + + private void handle_function_column + ( + final IDs local_id + ) + { + Functions.add_entry + ( + "column", + local_id, + Strings.get_id_from_string + ( + XMLManager.get_attribute(xml_node, "col") + ) + ); + } + + private void handle_function_label + ( + final IDs local_id + ) + { + Functions.add_entry + ( + "label", + local_id, + Strings.get_id_from_string + ( + XMLManager.get_attribute(xml_node, "label") + ) + ); + } + + /***************************************************************************/ + /** Predicates *************************************************************/ + /***************************************************************************/ + private void handle_predicate_port_maps + ( + final IDs local_id, + final Node linked_entity + ) + throws XPathExpressionException + { + final NodeList port_maps, real_ports; + final int port_maps_length; + + port_maps = + (NodeList) XPE_FIND_PORT_MAPS.evaluate + ( + xml_node, + XPathConstants.NODESET + ); + + real_ports = + (NodeList) XPE_FIND_REAL_PORTS.evaluate + ( + linked_entity, + XPathConstants.NODESET + ); + + port_maps_length = port_maps.getLength(); + + for (int i = 0; i < port_maps_length; ++i) + { + final Node mapping, formal_name, actual_waveform; + + mapping = port_maps.item(i); + + actual_waveform = + (Node) XPE_FIND_ACTUAL_NE.evaluate + ( + mapping, + XPathConstants.NODE + ); + + formal_name = + (Node) XPE_FIND_FORMAL.evaluate + ( + mapping, + XPathConstants.NODE + ); + + if (formal_name == null) + { + Predicates.add_entry + ( + "port_maps", + local_id, + Waveforms.get_associated_waveform_id + ( + IDs.get_id_from_xml_id + ( + XMLManager.get_attribute(actual_waveform, "ref"), + null + ) + ), + IDs.get_id_from_xml_id + ( + XMLManager.get_attribute(real_ports.item(i), "id"), + "port" + ) + ); + } + else + { + final XPathExpression xpe_find_true_port; + final Node true_port; + + xpe_find_true_port = + XMLManager.compile_or_die + ( + "./port_chain/el[@identifier=\"" + + XMLManager.get_attribute(formal_name, "identifier") + + "\"]" + ); + + true_port = + (Node) xpe_find_true_port.evaluate + ( + linked_entity, + XPathConstants.NODE + ); + + Predicates.add_entry + ( + "port_maps", + local_id, + Waveforms.get_associated_waveform_id + ( + IDs.get_id_from_xml_id + ( + XMLManager.get_attribute(actual_waveform, "ref"), + null + ) + ), + IDs.get_id_from_xml_id + ( + XMLManager.get_attribute(true_port, "id"), + "port" + ) + ); + } + } + } + + private void handle_predicate_generic_maps + ( + final IDs local_id, + final Node linked_entity + ) + throws XPathExpressionException + { + /* TODO */ + } +} diff --git a/src/ghdl2hastabel/vhdl/Entity.java b/src/ghdl2hastabel/vhdl/Entity.java new file mode 100644 index 0000000..607a0d9 --- /dev/null +++ b/src/ghdl2hastabel/vhdl/Entity.java @@ -0,0 +1,290 @@ +package ghdl2hastabel.vhdl; + +import ghdl2hastabel.Strings; +import ghdl2hastabel.Functions; +import ghdl2hastabel.Predicates; +import ghdl2hastabel.ParsableXML; +import ghdl2hastabel.XMLManager; +import ghdl2hastabel.IDs; + +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpression; +import javax.xml.xpath.XPathExpressionException; + +import java.util.Stack; + +public class Entity extends ParsableXML +{ + private static final XPathExpression XPE_FIND_PORTS; + private static final XPathExpression XPE_FIND_GENERICS; + + static + { + XPE_FIND_PORTS = + XMLManager.compile_or_die + ( + "./port_chain/el[@kind=\"interface_signal_declaration\"]" + ); + + XPE_FIND_GENERICS = + XMLManager.compile_or_die + ( + "./generic_chain/el[@kind=\"interface_constant_declaration\"]" + ); + } + + public Entity + ( + final IDs parent_id, + final Node xml_node + ) + { + super(parent_id, xml_node); + } + + @Override + public void parse + ( + final Stack<ParsableXML> waiting_list + ) + throws XPathExpressionException + { + final String xml_id; + final IDs local_id; + + xml_id = XMLManager.get_attribute(xml_node, "id"); + + local_id = IDs.get_id_from_xml_id(xml_id, "entity"); + + /** Parent **************************************************************/ + handle_link_to_file(local_id); + + /** Functions ***********************************************************/ + handle_function_line(local_id); + handle_function_column(local_id); + handle_function_identifier(local_id); + + /** Predicates **********************************************************/ + handle_predicate_has_begin(local_id); + handle_predicate_has_visible_flag(local_id); + handle_predicate_is_withing_flag(local_id); + handle_predicate_end_has_reserved_id(local_id); + handle_predicate_end_has_identifier(local_id); + + /** Children ************************************************************/ + handle_child_ports(local_id, waiting_list); + handle_child_generics(local_id, waiting_list); + } + + /***************************************************************************/ + /** Parents ****************************************************************/ + /***************************************************************************/ + private void handle_link_to_file + ( + final IDs local_id + ) + { + Predicates.add_entry("is_in_file", local_id, parent_id); + } + + + /***************************************************************************/ + /** Functions **************************************************************/ + /***************************************************************************/ + private void handle_function_line + ( + final IDs local_id + ) + { + Functions.add_entry + ( + "line", + local_id, + Strings.get_id_from_string + ( + XMLManager.get_attribute(xml_node, "line") + ) + ); + } + + private void handle_function_column + ( + final IDs local_id + ) + { + Functions.add_entry + ( + "column", + local_id, + Strings.get_id_from_string + ( + XMLManager.get_attribute(xml_node, "col") + ) + ); + } + + private void handle_function_identifier + ( + final IDs local_id + ) + { + Functions.add_entry + ( + "identifier", + local_id, + Strings.get_id_from_string + ( + XMLManager.get_attribute(xml_node, "col") + ) + ); + } + + /***************************************************************************/ + /** Predicates *************************************************************/ + /***************************************************************************/ + private void handle_predicate_has_begin + ( + final IDs local_id + ) + { + if + ( + XMLManager.get_attribute + ( + xml_node, + "has_begin" + ).equals("true") + ) + { + Predicates.add_entry("has_begin", local_id); + } + } + + private void handle_predicate_has_visible_flag + ( + final IDs local_id + ) + { + if + ( + XMLManager.get_attribute + ( + xml_node, + "visible_flag" + ).equals("true") + ) + { + Predicates.add_entry("has_visible_flag", local_id); + } + } + + private void handle_predicate_is_withing_flag + ( + final IDs local_id + ) + { + if + ( + XMLManager.get_attribute + ( + xml_node, + "is_within_flag" + ).equals("true") + ) + { + Predicates.add_entry("is_within_flag", local_id); + } + } + + private void handle_predicate_end_has_reserved_id + ( + final IDs local_id + ) + { + if + ( + XMLManager.get_attribute + ( + xml_node, + "end_has_reserved_id" + ).equals("true") + ) + { + Predicates.add_entry("end_has_reserved_id", local_id); + } + } + + private void handle_predicate_end_has_identifier + ( + final IDs local_id + ) + { + if + ( + XMLManager.get_attribute + ( + xml_node, + "end_has_identifier" + ).equals("true") + ) + { + Predicates.add_entry("end_has_identifier", local_id); + } + } + + /***************************************************************************/ + /** Children ***************************************************************/ + /***************************************************************************/ + private void handle_child_ports + ( + final IDs local_id, + final Stack<ParsableXML> waiting_list + ) + throws XPathExpressionException + { + final NodeList ports; + final int children_count; + + ports = + (NodeList) XPE_FIND_PORTS.evaluate + ( + xml_node, + XPathConstants.NODESET + ); + + children_count = ports.getLength(); + + for (int i = 0; i < children_count; ++i) + { + waiting_list.push(new Port(local_id, ports.item(i))); + } + } + + private void handle_child_generics + ( + final IDs local_id, + final Stack<ParsableXML> waiting_list + ) + throws XPathExpressionException + { + final NodeList generics; + final int children_count; + + generics = + (NodeList) XPE_FIND_GENERICS.evaluate + ( + xml_node, + XPathConstants.NODESET + ); + + children_count = generics.getLength(); + + for (int i = 0; i < children_count; ++i) + { + waiting_list.push(new Generic(local_id, generics.item(i))); + } + } +} diff --git a/src/ghdl2hastabel/vhdl/File.java b/src/ghdl2hastabel/vhdl/File.java new file mode 100644 index 0000000..c321eb2 --- /dev/null +++ b/src/ghdl2hastabel/vhdl/File.java @@ -0,0 +1,145 @@ +package ghdl2hastabel.vhdl; + +import ghdl2hastabel.Strings; +import ghdl2hastabel.Functions; +import ghdl2hastabel.ParsableXML; +import ghdl2hastabel.XMLManager; +import ghdl2hastabel.IDs; + +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpression; +import javax.xml.xpath.XPathExpressionException; + +import java.util.Stack; + +public class File extends ParsableXML +{ + private static final XPathExpression XPE_FIND_ENTITIES; + private static final XPathExpression XPE_FIND_ARCHITECTURES; + + static + { + XPE_FIND_ENTITIES = + XMLManager.compile_or_die + ( + "./*/*/library_unit[@kind=\"entity_declaration\"]" + ); + + XPE_FIND_ARCHITECTURES = + XMLManager.compile_or_die + ( + "./*/*/library_unit[@kind=\"architecture_body\"]" + ); + } + + public File + ( + final IDs parent_id, + final Node xml_node + ) + { + super(parent_id, xml_node); + } + + @Override + public void parse + ( + final Stack<ParsableXML> waiting_list + ) + throws XPathExpressionException + { + final String xml_id; + final IDs local_id; + + xml_id = XMLManager.get_attribute(xml_node, "id"); + + local_id = IDs.get_id_from_xml_id(xml_id, "file"); + + /** Functions ***********************************************************/ + handle_function_filename(local_id); + + /** Predicates **********************************************************/ + + /** Children ************************************************************/ + handle_child_entities(local_id, waiting_list); + handle_child_architectures(local_id, waiting_list); + } + + /***************************************************************************/ + /** Functions **************************************************************/ + /***************************************************************************/ + private void handle_function_filename + ( + final IDs local_id + ) + { + Functions.add_entry + ( + "filename", + local_id, + Strings.get_id_from_string + ( + XMLManager.get_attribute(xml_node, "file") + ) + ); + } + + /***************************************************************************/ + /** Children ***************************************************************/ + /***************************************************************************/ + private void handle_child_entities + ( + final IDs local_id, + final Stack<ParsableXML> waiting_list + ) + throws XPathExpressionException + { + final NodeList entities; + final int children_count; + + entities = + (NodeList) XPE_FIND_ENTITIES.evaluate + ( + xml_node, + XPathConstants.NODESET + ); + + children_count = entities.getLength(); + + for (int i = 0; i < children_count; ++i) + { + waiting_list.push(new Entity(local_id, entities.item(i))); + } + } + + private void handle_child_architectures + ( + final IDs local_id, + final Stack<ParsableXML> waiting_list + ) + throws XPathExpressionException + { + final NodeList architectures; + final int children_count; + + architectures = + (NodeList) XPE_FIND_ARCHITECTURES.evaluate + ( + xml_node, + XPathConstants.NODESET + ); + + children_count = architectures.getLength(); + + for (int i = 0; i < children_count; ++i) + { + waiting_list.push + ( + new Architecture(local_id, architectures.item(i)) + ); + } + } +} diff --git a/src/ghdl2hastabel/vhdl/Generic.java b/src/ghdl2hastabel/vhdl/Generic.java new file mode 100644 index 0000000..3b86585 --- /dev/null +++ b/src/ghdl2hastabel/vhdl/Generic.java @@ -0,0 +1,257 @@ +package ghdl2hastabel.vhdl; + +import ghdl2hastabel.Strings; +import ghdl2hastabel.Waveforms; +import ghdl2hastabel.Functions; +import ghdl2hastabel.Predicates; +import ghdl2hastabel.ParsableXML; +import ghdl2hastabel.XMLManager; +import ghdl2hastabel.IDs; + +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpression; +import javax.xml.xpath.XPathExpressionException; + +import java.util.Stack; + +public class Generic extends ParsableXML +{ + public Generic + ( + final IDs parent_id, + final Node xml_node + ) + { + super(parent_id, xml_node); + } + + @Override + public void parse + ( + final Stack<ParsableXML> waiting_list + ) + throws XPathExpressionException + { + final String xml_id; + final IDs local_id; + + xml_id = XMLManager.get_attribute(xml_node, "id"); + + local_id = IDs.get_id_from_xml_id(xml_id, "generic"); + + /** Parent **************************************************************/ + handle_link_to_entity(local_id); + + /** Functions ***********************************************************/ + handle_function_line(local_id); + handle_function_column(local_id); + handle_function_identifier(local_id); + + /** Predicates **********************************************************/ + handle_predicate_has_class(local_id); + handle_predicate_is_ref(local_id); + handle_predicate_has_identifier_list(local_id); + handle_predicate_has_visible_flag(local_id); + handle_predicate_has_after_drivers_flag(local_id); + handle_predicate_has_use_flag(local_id); + + /** Children ************************************************************/ + handle_child_waveform(local_id); + } + + /***************************************************************************/ + /** Parents ****************************************************************/ + /***************************************************************************/ + private void handle_link_to_entity + ( + final IDs local_id + ) + { + Predicates.add_entry("is_port_of", local_id, parent_id); + } + + + /***************************************************************************/ + /** Functions **************************************************************/ + /***************************************************************************/ + private void handle_function_line + ( + final IDs local_id + ) + { + Functions.add_entry + ( + "line", + local_id, + Strings.get_id_from_string + ( + XMLManager.get_attribute(xml_node, "line") + ) + ); + } + + private void handle_function_column + ( + final IDs local_id + ) + { + Functions.add_entry + ( + "column", + local_id, + Strings.get_id_from_string + ( + XMLManager.get_attribute(xml_node, "col") + ) + ); + } + + private void handle_function_identifier + ( + final IDs local_id + ) + { + Functions.add_entry + ( + "identifier", + local_id, + Strings.get_id_from_string + ( + XMLManager.get_attribute(xml_node, "identifier") + ) + ); + } + + /***************************************************************************/ + /** Predicates *************************************************************/ + /***************************************************************************/ + private void handle_predicate_has_class + ( + final IDs local_id + ) + { + if + ( + XMLManager.get_attribute + ( + xml_node, + "has_class" + ).equals("true") + ) + { + Predicates.add_entry("has_class", local_id); + } + } + + private void handle_predicate_is_ref + ( + final IDs local_id + ) + { + if + ( + XMLManager.get_attribute + ( + xml_node, + "is_ref" + ).equals("true") + ) + { + Predicates.add_entry("is_ref", local_id); + } + } + + private void handle_predicate_has_identifier_list + ( + final IDs local_id + ) + { + if + ( + XMLManager.get_attribute + ( + xml_node, + "has_identifier_list" + ).equals("true") + ) + { + Predicates.add_entry("has_identifier_list", local_id); + } + } + + private void handle_predicate_has_visible_flag + ( + final IDs local_id + ) + { + if + ( + XMLManager.get_attribute + ( + xml_node, + "visible_flag" + ).equals("true") + ) + { + Predicates.add_entry("has_visible_flag", local_id); + } + } + + private void handle_predicate_has_after_drivers_flag + ( + final IDs local_id + ) + { + if + ( + XMLManager.get_attribute + ( + xml_node, + "after_drivers_flag" + ).equals("true") + ) + { + Predicates.add_entry("has_after_drivers_flag", local_id); + } + } + + private void handle_predicate_has_use_flag + ( + final IDs local_id + ) + { + if + ( + XMLManager.get_attribute + ( + xml_node, + "use_flag" + ).equals("true") + ) + { + Predicates.add_entry("has_use_flag", local_id); + } + } + + /***************************************************************************/ + /** Children ***************************************************************/ + /***************************************************************************/ + private void handle_child_waveform + ( + final IDs local_id + ) + { + Predicates.add_entry + ( + "is_waveform_of", + Waveforms.get_associated_waveform_id + ( + local_id + ), + local_id + ); + } +} diff --git a/src/ghdl2hastabel/vhdl/ISNode.java b/src/ghdl2hastabel/vhdl/ISNode.java new file mode 100644 index 0000000..d09a815 --- /dev/null +++ b/src/ghdl2hastabel/vhdl/ISNode.java @@ -0,0 +1,273 @@ +package ghdl2hastabel.vhdl; + +import ghdl2hastabel.Depths; +import ghdl2hastabel.OutputFile; +import ghdl2hastabel.Strings; +import ghdl2hastabel.Functions; +import ghdl2hastabel.Predicates; +import ghdl2hastabel.ParsableXML; +import ghdl2hastabel.XMLManager; +import ghdl2hastabel.IDs; + +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpression; +import javax.xml.xpath.XPathExpressionException; + +import java.util.Stack; + +/* If Statement Node */ +public class ISNode extends ghdl2hastabel.vhdl.Node +{ + private static final XPathExpression XPE_FIND_SOURCES; + private static final XPathExpression XPE_FIND_TRUE_BRANCH; + private static final XPathExpression XPE_FIND_ELSE_BRANCH; + + static + { + XPE_FIND_SOURCES = + XMLManager.compile_or_die + ( + "./condition" /* //named_entity" */ + ); + + XPE_FIND_TRUE_BRANCH = + XMLManager.compile_or_die + ( + "./sequential_statement_chain" + ); + + XPE_FIND_ELSE_BRANCH = + XMLManager.compile_or_die + ( + "./else_clause/sequential_statement_chain" + ); + } + + public ISNode + ( + final OutputFile output, + final IDs parent_id, + final Node xml_node, + final IDs next_node, + final int depth, + final String[] attributes + ) + { + super + ( + output, + parent_id, + xml_node, + next_node, + depth, + attributes + ); + } + + @Override + public void parse + ( + final Stack<ParsableXML> waiting_list + ) + throws XPathExpressionException + { + final String xml_id; + final IDs local_id; + + xml_id = XMLManager.get_attribute(xml_node, "id"); + + local_id = IDs.get_id_from_xml_id(output, xml_id, "node"); + + /** Functions ***********************************************************/ + handle_function_label(local_id); + handle_function_kind(local_id); + handle_function_depth(local_id); + + /** Predicates **********************************************************/ + handle_predicate_has_option(local_id); + handle_predicate_expr_reads(local_id); + + /** Children ************************************************************/ + handle_true_branch(local_id, waiting_list); + handle_else_branch(local_id, waiting_list); + } + + /***************************************************************************/ + /** Functions **************************************************************/ + /***************************************************************************/ + private void handle_function_label + ( + final IDs local_id + ) + { + Functions.add_entry + ( + output, + "label", + local_id, + Strings.get_id_from_string + ( + XMLManager.get_attribute(xml_node, "label") + ) + ); + } + + private void handle_function_kind + ( + final IDs local_id + ) + { + Functions.add_entry + ( + output, + "kind", + local_id, + Strings.get_id_from_string("if") + ); + } + + private void handle_function_depth + ( + final IDs local_id + ) + { + Functions.add_entry + ( + output, + "depth", + local_id, + Depths.get_id_from_depth(new Integer(depth)) + ); + } + + /***************************************************************************/ + /** Predicates *************************************************************/ + /***************************************************************************/ + private void handle_predicate_has_option + ( + final IDs local_id + ) + { + for (final String s: attributes) + { + Predicates.add_entry + ( + output, + "has_option", + local_id, + Strings.get_id_from_string(s) + ); + } + } + + private void handle_predicate_expr_reads + ( + final IDs local_id + ) + throws XPathExpressionException + { + final Node sources; + + sources = + (Node) XPE_FIND_SOURCES.evaluate + ( + xml_node, + XPathConstants.NODE + ); + + handle_read_expr_predicates(local_id, sources); + } + + /***************************************************************************/ + /** Children ***************************************************************/ + /***************************************************************************/ + private void handle_true_branch + ( + final IDs local_id, + final Stack<ParsableXML> waiting_list + ) + throws XPathExpressionException + { + final Node true_branch; + + true_branch = + (Node) XPE_FIND_TRUE_BRANCH.evaluate + ( + xml_node, + XPathConstants.NODE + ); + + waiting_list.push + ( + new SSCNode + ( + output, + parent_id, + true_branch, + local_id, + next_node, + (depth + 1), + new String[] {"COND_WAS_TRUE"} + ) + ); + } + + private void handle_else_branch + ( + final IDs local_id, + final Stack<ParsableXML> waiting_list + ) + throws XPathExpressionException + { + final Node else_branch; + + else_branch = + (Node) XPE_FIND_ELSE_BRANCH.evaluate + ( + xml_node, + XPathConstants.NODE + ); + + if (else_branch == (Node) null) + { + if (next_node == (IDs) null) + { + Predicates.add_entry + ( + output, + "is_terminal", + local_id + ); + } + else + { + Predicates.add_entry + ( + output, + "node_connect", + local_id, + next_node + ); + } + } + else + { + waiting_list.push + ( + new SSCNode + ( + output, + parent_id, + else_branch, + local_id, + next_node, + (depth + 1), + new String[] {"COND_WAS_FALSE"} + ) + ); + } + } +} diff --git a/src/ghdl2hastabel/vhdl/Node.java b/src/ghdl2hastabel/vhdl/Node.java new file mode 100644 index 0000000..3469277 --- /dev/null +++ b/src/ghdl2hastabel/vhdl/Node.java @@ -0,0 +1,137 @@ +package ghdl2hastabel.vhdl; + +import ghdl2hastabel.Expressions; +import ghdl2hastabel.OutputFile; +import ghdl2hastabel.Strings; +import ghdl2hastabel.Predicates; +import ghdl2hastabel.ParsableXML; +import ghdl2hastabel.IDs; + +import java.util.ArrayList; +import java.util.List; + +import javax.xml.xpath.XPathExpressionException; + +public abstract class Node extends ParsableXML +{ + protected final IDs next_node; + protected final int depth; + protected final String[] attributes; + protected final OutputFile output; + + public Node + ( + final OutputFile output, + final IDs parent_id, + final org.w3c.dom.Node xml_node, + final IDs next_node, + final int depth, + final String[] attributes + ) + { + super(parent_id, xml_node); + + this.output = output; + this.next_node = next_node; + this.depth = depth; + this.attributes = attributes; + } + + protected void handle_read_expr_predicates + ( + final IDs local_id, + final org.w3c.dom.Node expr_node + ) + throws XPathExpressionException + { + final List<IDs> elements; + final StringBuilder structure; + final int elements_count; + + elements = new ArrayList<IDs>(); + structure = new StringBuilder(); + + Expressions.process(elements, structure, expr_node); + + Predicates.add_entry + ( + output, + "is_read_structure", + local_id, + Strings.get_id_from_string + ( + structure.toString() + ) + ); + + elements_count = elements.size(); + + for (int i = 0; i < elements_count; ++i) + { + Predicates.add_entry + ( + output, + "is_read_element", + local_id, + Strings.get_id_from_string(Integer.toString(i)), + elements.get(i) + ); + + Predicates.add_entry + ( + "is_accessed_by", + elements.get(i), + parent_id + ); + } + } + + protected void handle_written_expr_predicates + ( + final IDs local_id, + final org.w3c.dom.Node expr_node + ) + throws XPathExpressionException + { + final List<IDs> elements; + final StringBuilder structure; + final int elements_count; + + elements = new ArrayList<IDs>(); + structure = new StringBuilder(); + + Expressions.process(elements, structure, expr_node); + + Predicates.add_entry + ( + output, + "is_written_structure", + local_id, + Strings.get_id_from_string + ( + structure.toString() + ) + ); + + elements_count = elements.size(); + + for (int i = 0; i < elements_count; ++i) + { + Predicates.add_entry + ( + output, + "is_written_element", + local_id, + Strings.get_id_from_string(Integer.toString(i)), + elements.get(i) + ); + + Predicates.add_entry + ( + "is_accessed_by", + elements.get(i), + parent_id + ); + } + } +} diff --git a/src/ghdl2hastabel/vhdl/Port.java b/src/ghdl2hastabel/vhdl/Port.java new file mode 100644 index 0000000..f1a30e6 --- /dev/null +++ b/src/ghdl2hastabel/vhdl/Port.java @@ -0,0 +1,365 @@ +package ghdl2hastabel.vhdl; + +import ghdl2hastabel.Strings; +import ghdl2hastabel.Waveforms; +import ghdl2hastabel.Functions; +import ghdl2hastabel.Predicates; +import ghdl2hastabel.ParsableXML; +import ghdl2hastabel.XMLManager; +import ghdl2hastabel.IDs; + +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpression; +import javax.xml.xpath.XPathExpressionException; + +import java.util.Stack; + +public class Port extends ParsableXML +{ + public Port + ( + final IDs parent_id, + final Node xml_node + ) + { + super(parent_id, xml_node); + } + + @Override + public void parse + ( + final Stack<ParsableXML> waiting_list + ) + throws XPathExpressionException + { + final String xml_id; + final IDs local_id; + + xml_id = XMLManager.get_attribute(xml_node, "id"); + + local_id = IDs.get_id_from_xml_id(xml_id, "port"); + + /** Parent **************************************************************/ + handle_link_to_entity(local_id); + + /** Functions ***********************************************************/ + handle_function_line(local_id); + handle_function_column(local_id); + handle_function_identifier(local_id); + + /** Predicates **********************************************************/ + handle_predicate_has_disconnect_flag(local_id); + handle_predicate_has_class(local_id); + handle_predicate_is_ref(local_id); + handle_predicate_has_active_flag(local_id); + handle_predicate_has_identifier_list(local_id); + handle_predicate_has_visible_flag(local_id); + handle_predicate_has_after_drivers_flag(local_id); + handle_predicate_has_use_flag(local_id); + handle_predicate_has_open_flag(local_id); + handle_predicate_has_guarded_signal_flag(local_id); + + handle_predicate_has_mode(local_id); + + /** Children ************************************************************/ + handle_child_waveform(local_id); + } + + /***************************************************************************/ + /** Parents ****************************************************************/ + /***************************************************************************/ + private void handle_link_to_entity + ( + final IDs local_id + ) + { + Predicates.add_entry("is_port_of", local_id, parent_id); + } + + + /***************************************************************************/ + /** Functions **************************************************************/ + /***************************************************************************/ + private void handle_function_line + ( + final IDs local_id + ) + { + Functions.add_entry + ( + "line", + local_id, + Strings.get_id_from_string + ( + XMLManager.get_attribute(xml_node, "line") + ) + ); + } + + private void handle_function_column + ( + final IDs local_id + ) + { + Functions.add_entry + ( + "column", + local_id, + Strings.get_id_from_string + ( + XMLManager.get_attribute(xml_node, "col") + ) + ); + } + + private void handle_function_identifier + ( + final IDs local_id + ) + { + Functions.add_entry + ( + "identifier", + local_id, + Strings.get_id_from_string + ( + XMLManager.get_attribute(xml_node, "identifier") + ) + ); + } + + /***************************************************************************/ + /** Predicates *************************************************************/ + /***************************************************************************/ + private void handle_predicate_has_disconnect_flag + ( + final IDs local_id + ) + { + if + ( + XMLManager.get_attribute + ( + xml_node, + "has_disconnect_flag" + ).equals("true") + ) + { + Predicates.add_entry("has_disconnect_flag", local_id); + } + } + + private void handle_predicate_has_class + ( + final IDs local_id + ) + { + if + ( + XMLManager.get_attribute + ( + xml_node, + "has_class" + ).equals("true") + ) + { + Predicates.add_entry("has_class", local_id); + } + } + + private void handle_predicate_is_ref + ( + final IDs local_id + ) + { + if + ( + XMLManager.get_attribute + ( + xml_node, + "is_ref" + ).equals("true") + ) + { + Predicates.add_entry("is_ref", local_id); + } + } + + private void handle_predicate_has_active_flag + ( + final IDs local_id + ) + { + if + ( + XMLManager.get_attribute + ( + xml_node, + "has_active_flag" + ).equals("true") + ) + { + Predicates.add_entry("has_active_flag", local_id); + } + } + + private void handle_predicate_has_identifier_list + ( + final IDs local_id + ) + { + if + ( + XMLManager.get_attribute + ( + xml_node, + "has_identifier_list" + ).equals("true") + ) + { + Predicates.add_entry("has_identifier_list", local_id); + } + } + + private void handle_predicate_has_visible_flag + ( + final IDs local_id + ) + { + if + ( + XMLManager.get_attribute + ( + xml_node, + "visible_flag" + ).equals("true") + ) + { + Predicates.add_entry("has_visible_flag", local_id); + } + } + + private void handle_predicate_has_after_drivers_flag + ( + final IDs local_id + ) + { + if + ( + XMLManager.get_attribute + ( + xml_node, + "after_drivers_flag" + ).equals("true") + ) + { + Predicates.add_entry("has_after_drivers_flag", local_id); + } + } + + private void handle_predicate_has_use_flag + ( + final IDs local_id + ) + { + if + ( + XMLManager.get_attribute + ( + xml_node, + "use_flag" + ).equals("true") + ) + { + Predicates.add_entry("has_use_flag", local_id); + } + } + + private void handle_predicate_has_open_flag + ( + final IDs local_id + ) + { + if + ( + XMLManager.get_attribute + ( + xml_node, + "open_flag" + ).equals("true") + ) + { + Predicates.add_entry("has_open_flag", local_id); + } + } + + private void handle_predicate_has_guarded_signal_flag + ( + final IDs local_id + ) + { + if + ( + XMLManager.get_attribute + ( + xml_node, + "guarded_signal_flag" + ).equals("true") + ) + { + Predicates.add_entry("has_guarded_signal_flag", local_id); + } + } + + private void handle_predicate_has_mode + ( + final IDs local_id + ) + { + if + ( + XMLManager.get_attribute + ( + xml_node, + "has_mode" + ).equals("true") + ) + { + Predicates.add_entry + ( + "has_mode", + local_id, + Strings.get_id_from_string + ( + XMLManager.get_attribute + ( + xml_node, + "mode" + ) + ) + ); + } + } + + /***************************************************************************/ + /** Children ***************************************************************/ + /***************************************************************************/ + private void handle_child_waveform + ( + final IDs local_id + ) + { + Predicates.add_entry + ( + "is_waveform_of", + Waveforms.get_associated_waveform_id + ( + local_id + ), + local_id + ); + } +} diff --git a/src/ghdl2hastabel/vhdl/Process.java b/src/ghdl2hastabel/vhdl/Process.java new file mode 100644 index 0000000..9f1a5f4 --- /dev/null +++ b/src/ghdl2hastabel/vhdl/Process.java @@ -0,0 +1,451 @@ +package ghdl2hastabel.vhdl; + +import ghdl2hastabel.OutputFile; +import ghdl2hastabel.Strings; +import ghdl2hastabel.Waveforms; +import ghdl2hastabel.Functions; +import ghdl2hastabel.Predicates; +import ghdl2hastabel.ParsableXML; +import ghdl2hastabel.XMLManager; +import ghdl2hastabel.IDs; + +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpression; +import javax.xml.xpath.XPathExpressionException; + +import java.util.Stack; + +public class Process extends ParsableXML +{ + private static final XPathExpression XPE_FIND_SL_ELEMENTS; + private static final XPathExpression XPE_FIND_START_NODE; + + static + { + XPE_FIND_SL_ELEMENTS = + XMLManager.compile_or_die + ( + "(./sensitivity_list/el/named_entity | ./sensitivity_list/el[@ref])" + ); + + XPE_FIND_START_NODE = + XMLManager.compile_or_die + ( + "./sequential_statement_chain" + ); + } + + public Process + ( + final IDs parent_id, + final Node xml_node + ) + { + super(parent_id, xml_node); + } + + @Override + public void parse + ( + final Stack<ParsableXML> waiting_list + ) + throws XPathExpressionException + { + final String xml_id; + final IDs local_id; + + xml_id = XMLManager.get_attribute(xml_node, "id"); + + local_id = IDs.get_id_from_xml_id(xml_id, "process"); + + /** Parent **************************************************************/ + handle_link_to_architecture(local_id); + + /** Functions ***********************************************************/ + handle_function_line(local_id); + handle_function_column(local_id); + handle_function_label(local_id); + + /** Predicates **********************************************************/ + handle_predicate_has_seen_flag(local_id); + handle_predicate_end_has_postponed(local_id); + handle_predicate_is_ref(local_id); + handle_predicate_has_passive_flag(local_id); + handle_predicate_has_postponed_flag(local_id); + handle_predicate_has_visible_flag(local_id); + handle_predicate_is_within_flag(local_id); + handle_predicate_has_label(local_id); + handle_predicate_has_is(local_id); + handle_predicate_end_has_reserved_id(local_id); + handle_predicate_end_has_identifier(local_id); + + handle_predicate_is_explicit_process(local_id); + handle_predicate_is_in_sensitivity_list(local_id); + + /** Children ************************************************************/ + handle_child_node(local_id, waiting_list); + } + + /***************************************************************************/ + /** Parents ****************************************************************/ + /***************************************************************************/ + private void handle_link_to_architecture + ( + final IDs local_id + ) + { + Predicates.add_entry("belongs_to_architecture", local_id, parent_id); + } + + /***************************************************************************/ + /** Functions **************************************************************/ + /***************************************************************************/ + private void handle_function_line + ( + final IDs local_id + ) + { + Functions.add_entry + ( + "line", + local_id, + Strings.get_id_from_string + ( + XMLManager.get_attribute(xml_node, "line") + ) + ); + } + + private void handle_function_column + ( + final IDs local_id + ) + { + Functions.add_entry + ( + "column", + local_id, + Strings.get_id_from_string + ( + XMLManager.get_attribute(xml_node, "col") + ) + ); + } + + private void handle_function_label + ( + final IDs local_id + ) + { + Functions.add_entry + ( + "label", + local_id, + Strings.get_id_from_string + ( + XMLManager.get_attribute(xml_node, "label") + ) + ); + } + + /***************************************************************************/ + /** Predicates *************************************************************/ + /***************************************************************************/ + private void handle_predicate_has_seen_flag + ( + final IDs local_id + ) + { + if + ( + XMLManager.get_attribute + ( + xml_node, + "seen_flag" + ).equals("true") + ) + { + Predicates.add_entry("has_seen_flag", local_id); + } + } + + private void handle_predicate_end_has_postponed + ( + final IDs local_id + ) + { + if + ( + XMLManager.get_attribute + ( + xml_node, + "end_has_postponed" + ).equals("true") + ) + { + Predicates.add_entry("end_has_postponed", local_id); + } + } + + private void handle_predicate_is_ref + ( + final IDs local_id + ) + { + if + ( + XMLManager.get_attribute + ( + xml_node, + "is_ref" + ).equals("true") + ) + { + Predicates.add_entry("is_ref", local_id); + } + } + + private void handle_predicate_has_passive_flag + ( + final IDs local_id + ) + { + if + ( + XMLManager.get_attribute + ( + xml_node, + "passive_flag" + ).equals("true") + ) + { + Predicates.add_entry("has_passive_flag", local_id); + } + } + + private void handle_predicate_has_postponed_flag + ( + final IDs local_id + ) + { + if + ( + XMLManager.get_attribute + ( + xml_node, + "postponed_flag" + ).equals("true") + ) + { + Predicates.add_entry("has_postponed_flag", local_id); + } + } + + private void handle_predicate_has_visible_flag + ( + final IDs local_id + ) + { + if + ( + XMLManager.get_attribute + ( + xml_node, + "visible_flag" + ).equals("true") + ) + { + Predicates.add_entry("has_visible_flag", local_id); + } + } + + private void handle_predicate_is_within_flag + ( + final IDs local_id + ) + { + if + ( + XMLManager.get_attribute + ( + xml_node, + "is_within_flag" + ).equals("true") + ) + { + Predicates.add_entry("is_within_flag", local_id); + } + } + + private void handle_predicate_has_label + ( + final IDs local_id + ) + { + if + ( + XMLManager.get_attribute + ( + xml_node, + "has_label" + ).equals("true") + ) + { + Predicates.add_entry("has_label", local_id); + } + } + + private void handle_predicate_has_is + ( + final IDs local_id + ) + { + if + ( + XMLManager.get_attribute + ( + xml_node, + "has_is" + ).equals("true") + ) + { + Predicates.add_entry("has_is", local_id); + } + } + + private void handle_predicate_end_has_reserved_id + ( + final IDs local_id + ) + { + if + ( + XMLManager.get_attribute + ( + xml_node, + "end_has_reserved_id" + ).equals("true") + ) + { + Predicates.add_entry("end_has_reserved_id", local_id); + } + } + + private void handle_predicate_end_has_identifier + ( + final IDs local_id + ) + { + if + ( + XMLManager.get_attribute + ( + xml_node, + "end_has_identifier" + ).equals("true") + ) + { + Predicates.add_entry("end_has_identifier", local_id); + } + } + + private void handle_predicate_is_explicit_process + ( + final IDs local_id + ) + { + if + ( + XMLManager.get_attribute + ( + xml_node, + "is_ref" + ).equals("false") + ) + { + Predicates.add_entry("is_explicit_process", local_id); + } + } + + private void handle_predicate_is_in_sensitivity_list + ( + final IDs local_id + ) + throws XPathExpressionException + { + final NodeList items; + final int items_count; + + items = + (NodeList) XPE_FIND_SL_ELEMENTS.evaluate + ( + xml_node, + XPathConstants.NODESET + ); + + items_count = items.getLength(); + + for (int i = 0; i < items_count; ++i) + { + Predicates.add_entry + ( + "is_in_sensitivity_list", + Waveforms.get_associated_waveform_id + ( + IDs.get_id_from_xml_id + ( + XMLManager.get_attribute + ( + items.item(i), + "ref" + ), + null + ) + ), + local_id + ); + } + } + + /***************************************************************************/ + /** Children ***************************************************************/ + /***************************************************************************/ + private void handle_child_node + ( + final IDs local_id, + final Stack<ParsableXML> waiting_list + ) + throws XPathExpressionException + { + final Node start_node; + + start_node = + (Node) XPE_FIND_START_NODE.evaluate + ( + xml_node, + XPathConstants.NODE + ); + + waiting_list.push + ( + new SSCNode + ( + OutputFile.new_output_file + ( + "cfg_" /* TODO: Prefix as parameter? */ + + Integer.toString(local_id.get_value()) + + ".mod" /* TODO: Suffix as parameter? */ + ), + local_id, + start_node, + null, /* There is nothing before this sequence. */ + null, /* There is nothing after this sequence. */ + 0, /* Depth starts at zero. */ + new String[0] /* No attributes. */ + ) + ); + } +} diff --git a/src/ghdl2hastabel/vhdl/SSASNode.java b/src/ghdl2hastabel/vhdl/SSASNode.java new file mode 100644 index 0000000..f5571a8 --- /dev/null +++ b/src/ghdl2hastabel/vhdl/SSASNode.java @@ -0,0 +1,292 @@ +package ghdl2hastabel.vhdl; + +import ghdl2hastabel.Depths; +import ghdl2hastabel.Main; +import ghdl2hastabel.OutputFile; +import ghdl2hastabel.Strings; +import ghdl2hastabel.Waveforms; +import ghdl2hastabel.Functions; +import ghdl2hastabel.Predicates; +import ghdl2hastabel.ParsableXML; +import ghdl2hastabel.XMLManager; +import ghdl2hastabel.IDs; + +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpression; +import javax.xml.xpath.XPathExpressionException; + +import java.util.Stack; + +/* Simple Signal Assignment Statement Node */ +public class SSASNode extends ghdl2hastabel.vhdl.Node +{ + private static final XPathExpression XPE_FIND_TARGET; + private static final XPathExpression XPE_FIND_SOURCES; + private static final XPathExpression XPE_FIND_PREFIXED_NE; + private static final XPathExpression XPE_FIND_NE; + + static + { + XPE_FIND_TARGET = XMLManager.compile_or_die("./target"); + + XPE_FIND_SOURCES = + XMLManager.compile_or_die + ( + "./waveform_chain/el/we_value"/* //named_entity" */ + ); + + XPE_FIND_PREFIXED_NE = XMLManager.compile_or_die("./prefix/named_entity"); + XPE_FIND_NE = XMLManager.compile_or_die("./named_entity"); + } + + public SSASNode + ( + final OutputFile output, + final IDs parent_id, + final Node xml_node, + final IDs next_node, + final int depth, + final String[] attributes + ) + { + super + ( + output, + parent_id, + xml_node, + next_node, + depth, + attributes + ); + } + + @Override + public void parse + ( + final Stack<ParsableXML> waiting_list + ) + throws XPathExpressionException + { + final String xml_id; + final IDs local_id; + + xml_id = XMLManager.get_attribute(xml_node, "id"); + + local_id = IDs.get_id_from_xml_id(output, xml_id, "node"); + + /** Functions ***********************************************************/ + handle_function_label(local_id); + handle_function_kind(local_id); + handle_function_depth(local_id); + + /** Predicates **********************************************************/ + handle_predicate_has_option(local_id); + handle_predicate_expr_reads(local_id); + handle_predicate_expr_writes(local_id); + + /** Children ************************************************************/ + handle_next_node(local_id); + } + + /***************************************************************************/ + /** Functions **************************************************************/ + /***************************************************************************/ + private void handle_function_label + ( + final IDs local_id + ) + { + Functions.add_entry + ( + output, + "label", + local_id, + Strings.get_id_from_string + ( + XMLManager.get_attribute(xml_node, "label") + ) + ); + } + + private void handle_function_kind + ( + final IDs local_id + ) + { + Functions.add_entry + ( + output, + "kind", + local_id, + Strings.get_id_from_string("signal_assignement") + ); + } + + private void handle_function_depth + ( + final IDs local_id + ) + { + Functions.add_entry + ( + output, + "depth", + local_id, + Depths.get_id_from_depth(new Integer(depth)) + ); + } + + /***************************************************************************/ + /** Predicates *************************************************************/ + /***************************************************************************/ + private void handle_predicate_has_option + ( + final IDs local_id + ) + { + for (final String s: attributes) + { + Predicates.add_entry + ( + output, + "has_option", + local_id, + Strings.get_id_from_string(s) + ); + } + } + + private void handle_predicate_expr_reads + ( + final IDs local_id + ) + throws XPathExpressionException + { + final Node sources; + + sources = + (Node) XPE_FIND_SOURCES.evaluate + ( + xml_node, + XPathConstants.NODE + ); + + handle_read_expr_predicates(local_id, sources); + } + + private void handle_predicate_expr_writes + ( + final IDs local_id + ) + throws XPathExpressionException + { + final IDs target_id; + Node target; + + target = + (Node) XPE_FIND_TARGET.evaluate + ( + xml_node, + XPathConstants.NODE + ); + + /* Oddly enough, we can get a target as a ref... */ + /* Let's get the real source! */ + while (target.getNodeName().equals("target")) + { + final XPathExpression xpe_find_source; + + if (XMLManager.get_attribute(target, "kind").equals("indexed_name")) + { + target = + (Node) XPE_FIND_PREFIXED_NE.evaluate + ( + target, + XPathConstants.NODE + ); + } + else + { + target = + (Node) XPE_FIND_NE.evaluate + ( + target, + XPathConstants.NODE + ); + } + + /* XXX "or_die" might be a bit abusive here. */ + xpe_find_source = + XMLManager.compile_or_die + ( + ".//*[@id=\"" + + XMLManager.get_attribute(target, "ref") + + "\"]" + ); + + target = + (Node) xpe_find_source.evaluate + ( + Main.get_xml_root(), + XPathConstants.NODE + ); + } + + target_id = + Waveforms.get_associated_waveform_id + ( + IDs.get_id_from_xml_id + ( + XMLManager.get_attribute(target, "id"), + (String) null + ) + ); + + Predicates.add_entry + ( + output, + "expr_writes", + local_id, + target_id + ); + + Predicates.add_entry + ( + "is_accessed_by", + target_id, + parent_id + ); + } + + /***************************************************************************/ + /** Children ***************************************************************/ + /***************************************************************************/ + private void handle_next_node + ( + final IDs local_id + ) + { + if (next_node == (IDs) null) + { + Predicates.add_entry + ( + output, + "is_terminal", + local_id + ); + } + else + { + Predicates.add_entry + ( + output, + "node_connect", + local_id, + next_node + ); + } + } +} diff --git a/src/ghdl2hastabel/vhdl/SSCNode.java b/src/ghdl2hastabel/vhdl/SSCNode.java new file mode 100644 index 0000000..77b151c --- /dev/null +++ b/src/ghdl2hastabel/vhdl/SSCNode.java @@ -0,0 +1,234 @@ +package ghdl2hastabel.vhdl; + +import ghdl2hastabel.OutputFile; +import ghdl2hastabel.Predicates; +import ghdl2hastabel.ParsableXML; +import ghdl2hastabel.XMLManager; +import ghdl2hastabel.IDs; + +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpression; +import javax.xml.xpath.XPathExpressionException; + +import java.util.Stack; + +/* Sequential Statement Chain Node */ +/* Not actually a node in the resulting model, though. */ +public class SSCNode extends ghdl2hastabel.vhdl.Node +{ + private static final XPathExpression XPE_FIND_SUB_NODES; + private final IDs prev_node; + + static + { + XPE_FIND_SUB_NODES = XMLManager.compile_or_die("./el"); + } + + public SSCNode + ( + final OutputFile output, + final IDs parent_id, + final Node xml_node, + final IDs prev_node, /* can't simply forward ref to SSC */ + final IDs next_node, + final int depth, + final String[] attributes + ) + { + super + ( + output, + parent_id, + xml_node, + next_node, + depth, + attributes + ); + + this.prev_node = prev_node; /* null when first node of the process */ + } + + @Override + public void parse + ( + final Stack<ParsableXML> waiting_list + ) + throws XPathExpressionException + { + final NodeList sub_nodes; + final int intermediary_nodes_count; + int i; + + /* Find all the nodes, in order, in this instruction chain */ + sub_nodes = + (NodeList) XPE_FIND_SUB_NODES.evaluate + ( + xml_node, + XPathConstants.NODESET + ); + + /* Don't handle the last node in the 'for' loop, see below. */ + intermediary_nodes_count = (sub_nodes.getLength() - 1); + + for (i = 0; i < intermediary_nodes_count; ++i) + { + /* Prepare the parsing of all those nodes throufh the waiting list. + * To do so, each node needs to be informed of the ID of the node that + * follows it. + */ + final IDs next_seq_node; + + /* Get the ID for the next node in the sequence */ + next_seq_node = + IDs.get_id_from_xml_id + ( + output, + XMLManager.get_attribute + ( + sub_nodes.item(i + 1), + "id" + ), + "node" + ); + + /* + * Add to the waiting list, 'i' indicates if the attributes inherited + * by the instruction sequence node should be passed along (it's only + * the case if i == 0). + */ + waiting_list.push(get_vhdl_node(sub_nodes.item(i), next_seq_node, i)); + } + + /* + * The last node of the sequence takes the node following the sequence + * as 'next_node', so it's handled separatly. + */ + waiting_list.push(get_vhdl_node(sub_nodes.item(i), next_node, i)); + + /* Handle the connection of the first node to the previous node. */ + handle_backward_connection(sub_nodes.item(0)); + } + + private ParsableXML get_vhdl_node + ( + final Node node, + final IDs next_node, + final int i + ) + { + final String node_kind; + final String[] attributes; + + node_kind = XMLManager.get_attribute(node, "kind"); + + if (i == 0) + { + /* Attributes are only inherited by the first node */ + attributes = this.attributes; + } + else + { + attributes = new String[0]; + } + + if (node_kind.equals("if_statement")) + { + return + new ISNode + ( + output, + parent_id, + node, + next_node, + depth, + attributes + ); + } + else if (node_kind.equals("simple_signal_assignment_statement")) + { + return + new SSASNode + ( + output, + parent_id, + node, + next_node, + depth, + attributes + ); + } + else if (node_kind.equals("case_statement")) + { + return + new CSNode + ( + output, + parent_id, + node, + next_node, + depth, + attributes + ); + } + + System.err.println + ( + "[E] Unimplemented instruction kind \"" + + node_kind + + "\" found in Sequential Statement Chain." + ); + + System.exit(-1); + + return null; + } + + private void handle_backward_connection + ( + final Node first_node + ) + { + final IDs first_node_id; + + first_node_id = + IDs.get_id_from_xml_id + ( + output, + XMLManager.get_attribute + ( + first_node, + "id" + ), + "node" + ); + + if (prev_node == null) + { + /* First node of the process */ + Predicates.add_entry + ( + output, + "is_start_node", + first_node_id, + parent_id + ); + } + else + { + /* + * Not the first node, so have the previous node connect to this one + * (which is the first of this instruction set). + */ + Predicates.add_entry + ( + output, + "node_connect", + prev_node, + first_node_id + ); + } + } +} diff --git a/src/ghdl2hastabel/vhdl/Signal.java b/src/ghdl2hastabel/vhdl/Signal.java new file mode 100644 index 0000000..6812529 --- /dev/null +++ b/src/ghdl2hastabel/vhdl/Signal.java @@ -0,0 +1,317 @@ +package ghdl2hastabel.vhdl; + +import ghdl2hastabel.Strings; +import ghdl2hastabel.Waveforms; +import ghdl2hastabel.Functions; +import ghdl2hastabel.Predicates; +import ghdl2hastabel.ParsableXML; +import ghdl2hastabel.XMLManager; +import ghdl2hastabel.IDs; + +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpression; +import javax.xml.xpath.XPathExpressionException; + +import java.util.Stack; + +public class Signal extends ParsableXML +{ + public Signal + ( + final IDs parent_id, + final Node xml_node + ) + { + super(parent_id, xml_node); + } + + @Override + public void parse + ( + final Stack<ParsableXML> waiting_list + ) + throws XPathExpressionException + { + final String xml_id; + final IDs local_id; + + xml_id = XMLManager.get_attribute(xml_node, "id"); + + local_id = IDs.get_id_from_xml_id(xml_id, "signal"); + + /** Parent **************************************************************/ + handle_link_to_architecture(local_id); + + /** Functions ***********************************************************/ + handle_function_line(local_id); + handle_function_column(local_id); + handle_function_identifier(local_id); + + /** Predicates **********************************************************/ + handle_predicate_has_disconnect_flag(local_id); + handle_predicate_is_ref(local_id); + handle_predicate_has_active_flag(local_id); + handle_predicate_has_identifier_list(local_id); + handle_predicate_has_visible_flag(local_id); + handle_predicate_has_after_drivers_flag(local_id); + handle_predicate_has_use_flag(local_id); + handle_predicate_has_guarded_signal_flag(local_id); + + handle_predicate_is_of_kind(local_id); + + /** Children ************************************************************/ + handle_child_waveform(local_id); + } + + /***************************************************************************/ + /** Parents ****************************************************************/ + /***************************************************************************/ + private void handle_link_to_architecture + ( + final IDs local_id + ) + { + Predicates.add_entry("belongs_to_architecture", local_id, parent_id); + } + + + /***************************************************************************/ + /** Functions **************************************************************/ + /***************************************************************************/ + private void handle_function_line + ( + final IDs local_id + ) + { + Functions.add_entry + ( + "line", + local_id, + Strings.get_id_from_string + ( + XMLManager.get_attribute(xml_node, "line") + ) + ); + } + + private void handle_function_column + ( + final IDs local_id + ) + { + Functions.add_entry + ( + "column", + local_id, + Strings.get_id_from_string + ( + XMLManager.get_attribute(xml_node, "col") + ) + ); + } + + private void handle_function_identifier + ( + final IDs local_id + ) + { + Functions.add_entry + ( + "identifier", + local_id, + Strings.get_id_from_string + ( + XMLManager.get_attribute(xml_node, "identifier") + ) + ); + } + + /***************************************************************************/ + /** Predicates *************************************************************/ + /***************************************************************************/ + private void handle_predicate_has_disconnect_flag + ( + final IDs local_id + ) + { + if + ( + XMLManager.get_attribute + ( + xml_node, + "has_disconnect_flag" + ).equals("true") + ) + { + Predicates.add_entry("has_disconnect_flag", local_id); + } + } + + private void handle_predicate_is_ref + ( + final IDs local_id + ) + { + if + ( + XMLManager.get_attribute + ( + xml_node, + "is_ref" + ).equals("true") + ) + { + Predicates.add_entry("is_ref", local_id); + } + } + + private void handle_predicate_has_active_flag + ( + final IDs local_id + ) + { + if + ( + XMLManager.get_attribute + ( + xml_node, + "has_active_flag" + ).equals("true") + ) + { + Predicates.add_entry("has_active_flag", local_id); + } + } + + private void handle_predicate_has_identifier_list + ( + final IDs local_id + ) + { + if + ( + XMLManager.get_attribute + ( + xml_node, + "has_identifier_list" + ).equals("true") + ) + { + Predicates.add_entry("has_identifier_list", local_id); + } + } + + private void handle_predicate_has_visible_flag + ( + final IDs local_id + ) + { + if + ( + XMLManager.get_attribute + ( + xml_node, + "visible_flag" + ).equals("true") + ) + { + Predicates.add_entry("has_visible_flag", local_id); + } + } + + private void handle_predicate_has_after_drivers_flag + ( + final IDs local_id + ) + { + if + ( + XMLManager.get_attribute + ( + xml_node, + "after_drivers_flag" + ).equals("true") + ) + { + Predicates.add_entry("has_after_drivers_flag", local_id); + } + } + + private void handle_predicate_has_use_flag + ( + final IDs local_id + ) + { + if + ( + XMLManager.get_attribute + ( + xml_node, + "use_flag" + ).equals("true") + ) + { + Predicates.add_entry("has_use_flag", local_id); + } + } + + private void handle_predicate_has_guarded_signal_flag + ( + final IDs local_id + ) + { + if + ( + XMLManager.get_attribute + ( + xml_node, + "guarded_signal_flag" + ).equals("true") + ) + { + Predicates.add_entry("has_guarded_signal_flag", local_id); + } + } + + private void handle_predicate_is_of_kind + ( + final IDs local_id + ) + { + Predicates.add_entry + ( + "is_of_kind", + local_id, + Strings.get_id_from_string + ( + XMLManager.get_attribute + ( + xml_node, + "signal_kind" + ) + ) + ); + } + + /***************************************************************************/ + /** Children ***************************************************************/ + /***************************************************************************/ + private void handle_child_waveform + ( + final IDs local_id + ) + { + Predicates.add_entry + ( + "is_waveform_of", + Waveforms.get_associated_waveform_id + ( + local_id + ), + local_id + ); + } +} diff --git a/src/ghdl2hastabel/vhdl/WNode.java b/src/ghdl2hastabel/vhdl/WNode.java new file mode 100644 index 0000000..cc3864a --- /dev/null +++ b/src/ghdl2hastabel/vhdl/WNode.java @@ -0,0 +1,211 @@ +package ghdl2hastabel.vhdl; + +import ghdl2hastabel.Depths; +import ghdl2hastabel.OutputFile; +import ghdl2hastabel.Strings; +import ghdl2hastabel.Functions; +import ghdl2hastabel.Predicates; +import ghdl2hastabel.ParsableXML; +import ghdl2hastabel.XMLManager; +import ghdl2hastabel.IDs; + +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpression; +import javax.xml.xpath.XPathExpressionException; + +import java.util.Stack; + +/* When Node */ +public class WNode extends ghdl2hastabel.vhdl.Node +{ + private static final XPathExpression XPE_FIND_SOURCES; + private static final XPathExpression XPE_FIND_BODY; + + static + { + XPE_FIND_SOURCES = + XMLManager.compile_or_die + ( + "./choice_expression" /* //named_entity" */ + ); + + XPE_FIND_BODY = + XMLManager.compile_or_die + ( + "./associated_chain" + ); + } + + public WNode + ( + final OutputFile output, + final IDs parent_id, + final Node xml_node, + final IDs next_node, + final int depth, + final String[] attributes + ) + { + super + ( + output, + parent_id, + xml_node, + next_node, + depth, + attributes + ); + } + + @Override + public void parse + ( + final Stack<ParsableXML> waiting_list + ) + throws XPathExpressionException + { + final String xml_id; + final IDs local_id; + + xml_id = XMLManager.get_attribute(xml_node, "id"); + + local_id = IDs.get_id_from_xml_id(output, xml_id, "node"); + + /** Functions ***********************************************************/ + handle_function_label(local_id); + handle_function_kind(local_id); + handle_function_depth(local_id); + + /** Predicates **********************************************************/ + handle_predicate_has_option(local_id); + handle_predicate_expr_reads(local_id); + + /** Children ************************************************************/ + handle_body(local_id, waiting_list); + } + + /***************************************************************************/ + /** Functions **************************************************************/ + /***************************************************************************/ + private void handle_function_label + ( + final IDs local_id + ) + { + Functions.add_entry + ( + output, + "label", + local_id, + Strings.get_id_from_string("") + ); + } + + private void handle_function_kind + ( + final IDs local_id + ) + { + Functions.add_entry + ( + output, + "kind", + local_id, + Strings.get_id_from_string("when") + ); + } + + private void handle_function_depth + ( + final IDs local_id + ) + { + Functions.add_entry + ( + output, + "depth", + local_id, + Depths.get_id_from_depth(new Integer(depth)) + ); + } + + /***************************************************************************/ + /** Predicates *************************************************************/ + /***************************************************************************/ + private void handle_predicate_has_option + ( + final IDs local_id + ) + { + for (final String s: attributes) + { + Predicates.add_entry + ( + output, + "has_option", + local_id, + Strings.get_id_from_string(s) + ); + } + } + + private void handle_predicate_expr_reads + ( + final IDs local_id + ) + throws XPathExpressionException + { + final Node sources; + + sources = + (Node) XPE_FIND_SOURCES.evaluate + ( + xml_node, + XPathConstants.NODE + ); + + if (sources != (Node) null) + { + /* Not "others" */ + handle_read_expr_predicates(local_id, sources); + } + } + + /***************************************************************************/ + /** Children ***************************************************************/ + /***************************************************************************/ + + private void handle_body + ( + final IDs local_id, + final Stack<ParsableXML> waiting_list + ) + throws XPathExpressionException + { + final Node body; + + body = + (Node) XPE_FIND_BODY.evaluate + ( + xml_node, + XPathConstants.NODE + ); + + waiting_list.push + ( + new SSCNode + ( + output, + parent_id, + body, + local_id, + next_node, + (depth + 1), + new String[] {"COND_WAS_TRUE"} + ) + ); + } +} |


