Added comments and cleaned up ast nodes and parser
This commit is contained in:
parent
ae2a3c64ef
commit
1ec0433cfe
|
@ -37,5 +37,5 @@ add_executable(SchemeEditor
|
|||
comdel/parser/comdel_lexer.cpp
|
||||
main.cpp
|
||||
mainwindow.ui
|
||||
comdel/domain/comdel_validator.cpp comdel/domain/comdel_validator.h comdel/display/attribute_dialog.cpp comdel/display/attribute_dialog.h comdel/display/name_dialog.cpp comdel/display/name_dialog.h comdel/domain/comdel_generator.cpp comdel/domain/comdel_generator.h comdel/display/library_list.cpp comdel/display/library_list.h application.cpp application.h comdel/display/single_automatic_dialog.cpp comdel/display/single_automatic_dialog.h comdel/parser/color.cpp comdel/parser/color.h)
|
||||
comdel/domain/comdel_validator.cpp comdel/domain/comdel_validator.h comdel/display/attribute_dialog.cpp comdel/display/attribute_dialog.h comdel/display/name_dialog.cpp comdel/display/name_dialog.h comdel/domain/comdel_generator.cpp comdel/domain/comdel_generator.h comdel/display/library_list.cpp comdel/display/library_list.h application.cpp application.h comdel/display/single_automatic_dialog.cpp comdel/display/single_automatic_dialog.h comdel/parser/color.h)
|
||||
target_link_libraries(SchemeEditor Qt5::Core Qt5::Gui Qt5::Widgets)
|
||||
|
|
|
@ -90,7 +90,7 @@ std::pair<bool, std::vector<domain::ValidationError>> Application::loadSchema(st
|
|||
}
|
||||
|
||||
} else {
|
||||
errorOutput << "Failed parsing library" << std::endl;
|
||||
errorOutput << "Failed schema library" << std::endl;
|
||||
return {false, errors};
|
||||
}
|
||||
|
||||
|
|
|
@ -82,11 +82,11 @@ namespace domain {
|
|||
|
||||
for (auto &inst: schema.componentInstances) {
|
||||
for (auto &pin: inst->component.getPins()) {
|
||||
if (pin.getConnection().getType() == PinConnection::REQUIRED) {
|
||||
if (pin.getConnection().has_value()) {
|
||||
if (!connectionExists(schema, inst, pin)) {
|
||||
context.instance = inst.get();
|
||||
context.attributes["instanceName"] = Value::fromString(inst->name);
|
||||
auto message = populateMessage(pin.getConnection().getMessage(), context);
|
||||
auto message = populateMessage(pin.getConnection().value(), context);
|
||||
errors.emplace_back(Action::ERROR, message);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,19 +2,7 @@
|
|||
|
||||
namespace domain {
|
||||
|
||||
PinConnection::PinConnection(std::string message, ConnectionType type)
|
||||
: message(message), type(type) {}
|
||||
|
||||
PinConnection::ConnectionType PinConnection::getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
std::string PinConnection::getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
|
||||
Pin::Pin(std::string name, PinType type, std::string tooltip, PinConnection connection, domain::ui::Pin pin,
|
||||
Pin::Pin(std::string name, PinType type, std::string tooltip, std::optional<std::string> connection, domain::ui::Pin pin,
|
||||
std::optional<std::vector<Value>> wires)
|
||||
: name(name), type(type), tooltip(tooltip), connection(connection), displayPin(pin), wires(wires) {}
|
||||
|
||||
|
@ -34,7 +22,7 @@ namespace domain {
|
|||
return displayPin;
|
||||
}
|
||||
|
||||
PinConnection &Pin::getConnection() {
|
||||
std::optional<std::string> Pin::getConnection() {
|
||||
return connection;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,25 +9,6 @@
|
|||
|
||||
namespace domain {
|
||||
|
||||
class PinConnection {
|
||||
public:
|
||||
enum ConnectionType {
|
||||
REQUIRED,
|
||||
OPTIONAL
|
||||
};
|
||||
|
||||
private:
|
||||
std::string message;
|
||||
ConnectionType type;
|
||||
|
||||
public:
|
||||
PinConnection(std::string message, ConnectionType type);
|
||||
|
||||
ConnectionType getType();
|
||||
|
||||
std::string getMessage();
|
||||
};
|
||||
|
||||
class Pin {
|
||||
public:
|
||||
enum PinType {
|
||||
|
@ -40,13 +21,13 @@ namespace domain {
|
|||
std::string name;
|
||||
PinType type;
|
||||
std::string tooltip;
|
||||
PinConnection connection;
|
||||
std::optional<std::string> connection;
|
||||
domain::ui::Pin displayPin;
|
||||
|
||||
std::optional<std::vector<Value>> wires;
|
||||
|
||||
public:
|
||||
Pin(std::string name, PinType type, std::string tooltip, PinConnection connection, domain::ui::Pin pin,
|
||||
Pin(std::string name, PinType type, std::string tooltip, std::optional<std::string> connection, domain::ui::Pin pin,
|
||||
std::optional<std::vector<Value>> wires);
|
||||
|
||||
std::string &getName();
|
||||
|
@ -57,7 +38,7 @@ namespace domain {
|
|||
|
||||
ui::Pin &getDisplayPin();
|
||||
|
||||
PinConnection &getConnection();
|
||||
std::optional<std::string> getConnection();
|
||||
|
||||
std::optional<std::vector<Value>> &getWires();
|
||||
};
|
||||
|
|
|
@ -81,20 +81,20 @@ namespace domain {
|
|||
|
||||
Value toType(ValueNode node, Value::ValueType type = Value::ValueType::UNDEFINED) {
|
||||
if (type == Value::MEMORY_REFERENCE) {
|
||||
if (node.getType() == ValueNode::NIL) {
|
||||
if (node.is(ValueNode::NIL)) {
|
||||
return Value::fromMemoryReference(nullopt);
|
||||
} else {
|
||||
return Value::fromMemoryReference(node.asIdentifier());
|
||||
}
|
||||
}
|
||||
|
||||
if (node.getType() == ValueNode::BOOL) {
|
||||
if (node.is(ValueNode::BOOL)) {
|
||||
return Value::fromBool(node.asBool());
|
||||
} else if (node.getType() == ValueNode::INT) {
|
||||
} else if (node.is(ValueNode::INT)) {
|
||||
return Value::fromInt(node.asInt());
|
||||
} else if (node.getType() == ValueNode::STRING) {
|
||||
} else if (node.is(ValueNode::STRING)) {
|
||||
return Value::fromString(node.asString());
|
||||
} else if (node.getType() == ValueNode::NIL) {
|
||||
} else if (node.is(ValueNode::NIL)) {
|
||||
return Value::fromNull();
|
||||
}
|
||||
return Value::fromReference(node.asIdentifier(), Value::UNDEFINED);
|
||||
|
@ -120,14 +120,6 @@ namespace domain {
|
|||
return Pin::IN_OUT;
|
||||
}
|
||||
|
||||
PinConnection::ConnectionType toType(PinConnectionNode::ConnectionType type) {
|
||||
if (type == PinConnectionNode::OPTIONAL) {
|
||||
return PinConnection::OPTIONAL;
|
||||
}
|
||||
return PinConnection::REQUIRED;
|
||||
}
|
||||
|
||||
|
||||
Popup::PopupType toType(PopupNode::PopupType type) {
|
||||
if (type == PopupNode::AUTOMATIC) {
|
||||
return Popup::AUTOMATIC;
|
||||
|
@ -274,7 +266,7 @@ namespace domain {
|
|||
|
||||
|
||||
std::optional<AddressSpace> SchemaCreator::loadAddressSpace(AddressSpaceNode node) {
|
||||
return AddressSpace(node.name.value, node.start.value, node.end.value);
|
||||
return AddressSpace(node.name.value, node.range.first.value, node.range.second.value);
|
||||
}
|
||||
|
||||
std::optional<Connection> SchemaCreator::loadConnection(ConnectionNode node) {
|
||||
|
@ -584,12 +576,10 @@ namespace domain {
|
|||
}
|
||||
ui::Pin displayPin = *display->getItems()[0].pin;
|
||||
|
||||
|
||||
if (!node.connection) {
|
||||
errors.emplace_back(node.span, "missing @connection");
|
||||
return nullopt;
|
||||
std::optional<std::string> connection = std::nullopt;
|
||||
if (node.connection) {
|
||||
connection = node.connection->asString();
|
||||
}
|
||||
auto connection = loadPinConnection(*node.connection);
|
||||
|
||||
std::optional<std::vector<Value>> wiresOpt = std::nullopt;
|
||||
if (node.wires.has_value()) {
|
||||
|
@ -610,47 +600,74 @@ namespace domain {
|
|||
return Pin(pinName, type, tooltip, connection, displayPin, wiresOpt);
|
||||
}
|
||||
|
||||
Color readColor(std::vector<SourceError>& errors, DisplayItemNode& item, std::string property, Color _default) {
|
||||
auto color = item.asColor(property, _default);
|
||||
if(!color.has_value()) {
|
||||
errors.emplace_back(item.span, "expected color");
|
||||
return _default;
|
||||
}
|
||||
return *color;
|
||||
}
|
||||
|
||||
std::string readString(std::vector<SourceError>& errors, DisplayItemNode& item, std::string property, std::string _default = "") {
|
||||
auto value = item.asString(property, _default);
|
||||
if(!value.has_value()) {
|
||||
errors.emplace_back(item.span, "expected string");
|
||||
return _default;
|
||||
}
|
||||
return *value;
|
||||
}
|
||||
|
||||
long long int readInt(std::vector<SourceError>& errors, DisplayItemNode& item, std::string property, long long int _default = 0) {
|
||||
auto value = item.asInt(property, _default);
|
||||
if(!value.has_value()) {
|
||||
errors.emplace_back(item.span, "expected int");
|
||||
return _default;
|
||||
}
|
||||
return *value;
|
||||
}
|
||||
|
||||
std::optional<Display> SchemaCreator::loadDisplay(DisplayNode node) {
|
||||
std::vector<ui::Item> items;
|
||||
for (auto &item: node.items) {
|
||||
ui::Item displayItem;
|
||||
std::string type = item.type.value;
|
||||
|
||||
auto fillColor = item.asColor(&errors, "fillColor", Color(255, 255, 255, 255));
|
||||
auto lineColor = item.asColor(&errors, "lineColor", Color(0, 0, 0, 255));
|
||||
auto fillColor = readColor(errors, item, "fillColor", Color(255, 255, 255, 255));
|
||||
auto lineColor = readColor(errors, item, "lineColor", Color(0, 0, 0, 255));
|
||||
|
||||
if (type == "text") {
|
||||
long long int x, y, w, h;
|
||||
std::string text;
|
||||
auto color = item.asColor(&errors, "color", Color(0, 0, 0, 255));
|
||||
x = item.asInt(&errors, "x");
|
||||
y = item.asInt(&errors, "y");
|
||||
w = item.asInt(&errors, "w");
|
||||
h = item.asInt(&errors, "h");
|
||||
text = item.asString(&errors, "text");
|
||||
auto color = readColor(errors, item, "color", Color(0, 0, 0, 255));
|
||||
x = readInt(errors, item, "x");
|
||||
y = readInt(errors, item, "y");
|
||||
w = readInt(errors, item, "w");
|
||||
h = readInt(errors, item, "h");
|
||||
text = readString(errors, item, "text");
|
||||
displayItem.text = ui::Text(x, y, w, h, text, color);
|
||||
} else if (type == "rect") {
|
||||
long long int x, y, w, h;
|
||||
x = item.asInt(&errors, "x");
|
||||
y = item.asInt(&errors, "y");
|
||||
w = item.asInt(&errors, "w");
|
||||
h = item.asInt(&errors, "h");
|
||||
x = readInt(errors, item, "x");
|
||||
y = readInt(errors, item, "y");
|
||||
w = readInt(errors, item, "w");
|
||||
h = readInt(errors, item, "h");
|
||||
displayItem.rect = ui::Rect(x, y, w, h, {lineColor, fillColor});
|
||||
} else if (type == "line") {
|
||||
long long int x1, y1, x2, y2;
|
||||
x1 = item.asInt(&errors, "x1");
|
||||
y1 = item.asInt(&errors, "y1");
|
||||
x2 = item.asInt(&errors, "x2");
|
||||
y2 = item.asInt(&errors, "y2");
|
||||
x1 = readInt(errors, item, "x1");
|
||||
y1 = readInt(errors, item, "y1");
|
||||
x2 = readInt(errors, item, "x2");
|
||||
y2 = readInt(errors, item, "y2");
|
||||
displayItem.line = ui::Line(x1, y1, x2, y2, {lineColor, fillColor});
|
||||
} else if (type == "pin") {
|
||||
long long int x, y, w, h;
|
||||
x = item.asInt(&errors, "x");
|
||||
y = item.asInt(&errors, "y");
|
||||
w = item.asInt(&errors, "w");
|
||||
h = item.asInt(&errors, "h");
|
||||
std::string _orientation = item.asString(&errors, "orientation", "bottom");
|
||||
std::string _pinType = item.asString(&errors, "type", "out");
|
||||
x = readInt(errors, item, "x");
|
||||
y = readInt(errors, item, "y");
|
||||
w = readInt(errors, item, "w");
|
||||
h = readInt(errors, item, "h");
|
||||
std::string _orientation = readString(errors, item, "orientation", "bottom");
|
||||
std::string _pinType = readString(errors, item, "type", "out");
|
||||
|
||||
ui::PinOrientation orientation;
|
||||
if (_orientation == "left") {
|
||||
|
@ -679,11 +696,11 @@ namespace domain {
|
|||
displayItem.pin = ui::Pin(x, y, w, h, orientation, pinType, {lineColor, fillColor});
|
||||
} else if (type == "bus") {
|
||||
long long int x, y, w, h;
|
||||
x = item.asInt(&errors, "x");
|
||||
y = item.asInt(&errors, "y");
|
||||
w = item.asInt(&errors, "w");
|
||||
h = item.asInt(&errors, "h");
|
||||
std::string _orientation = item.asString(&errors, "orientation", "bottom");
|
||||
x = readInt(errors, item, "x");
|
||||
y = readInt(errors, item, "y");
|
||||
w = readInt(errors, item, "w");
|
||||
h = readInt(errors, item, "h");
|
||||
std::string _orientation = readString(errors, item, "orientation", "bottom");
|
||||
|
||||
ui::BusOrientation orientation;
|
||||
if (_orientation == "horizontal") {
|
||||
|
@ -703,13 +720,6 @@ namespace domain {
|
|||
return Display(items);
|
||||
}
|
||||
|
||||
|
||||
PinConnection SchemaCreator::loadPinConnection(PinConnectionNode node) {
|
||||
std::string message = node.message.asString();
|
||||
PinConnection::ConnectionType type = toType(node.type.value);
|
||||
return {message, type};
|
||||
}
|
||||
|
||||
std::optional<Attribute> SchemaCreator::loadAttribute(AttributeNode node) {
|
||||
std::string name = node.name.value;
|
||||
pushAdditional(name);
|
||||
|
|
|
@ -58,8 +58,6 @@ namespace domain {
|
|||
std::optional<Wire> loadWire(WireNode node);
|
||||
std::optional<Pin> loadPin(PinNode pins);
|
||||
|
||||
PinConnection loadPinConnection(PinConnectionNode node);
|
||||
|
||||
std::optional<Connection> loadConnection(ConnectionNode node);
|
||||
std::optional<Bus> loadBus(BusNode node);
|
||||
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
#include "ast_nodes.h"
|
||||
|
||||
/*************************** AST NODE ********************************/
|
||||
|
||||
AstNode::~AstNode() = default;
|
||||
|
||||
/*************************** NUMBER NODE ********************************/
|
||||
|
||||
NumberNode::NumberNode(const std::string &expression) {
|
||||
|
@ -41,7 +37,11 @@ std::string StringNode::asString() {
|
|||
|
||||
/*************************** VALUE NODE ********************************/
|
||||
|
||||
long long ValueNode::asInt() {
|
||||
ValueNode::ValueType ValueNode::getType() const {
|
||||
return type.value;
|
||||
}
|
||||
|
||||
long long int ValueNode::asInt() {
|
||||
if (is(INT)) {
|
||||
return intValue.value();
|
||||
}
|
||||
|
@ -134,4 +134,39 @@ ValueNode ValueNode::ofMemory(std::optional<std::string> _value) {
|
|||
value.type = EnumNode(MEMORY);
|
||||
value.identifierValue = _value;
|
||||
return value;
|
||||
}
|
||||
|
||||
/*************************** DisplayItem NODE ********************************/
|
||||
|
||||
std::optional<long long int> DisplayItemNode::asInt(const std::string &property, long long int _default) {
|
||||
auto prop = getProperty(property);
|
||||
if(prop.has_value()) {
|
||||
return prop->value.is(ValueNode::INT) ? std::optional(prop->value.asInt()) : std::nullopt;
|
||||
}
|
||||
return _default;
|
||||
}
|
||||
|
||||
std::optional<Color> DisplayItemNode::asColor(const std::string &property, Color _default) {
|
||||
auto prop = getProperty(property);
|
||||
if(prop.has_value()) {
|
||||
return prop->value.is(ValueNode::COLOR) ? std::optional(prop->value.asColor()) : std::nullopt;
|
||||
}
|
||||
return _default;
|
||||
}
|
||||
|
||||
std::optional<std::string> DisplayItemNode::asString(const std::string &property, std::string _default) {
|
||||
auto prop = getProperty(property);
|
||||
if(prop.has_value()) {
|
||||
return prop->value.is(ValueNode::STRING) ? std::optional(prop->value.asString()) : std::nullopt;
|
||||
}
|
||||
return _default;
|
||||
}
|
||||
|
||||
std::optional<PropertyNode> DisplayItemNode::getProperty(const std::string &property) {
|
||||
for(auto &prop: values) {
|
||||
if(prop.key.value == property) {
|
||||
return prop;
|
||||
}
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
|
@ -8,28 +8,30 @@
|
|||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
/*****************************************************************************
|
||||
* BASE TYPES *
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* AST base class, all AST node classes extend this class. Class contains basic
|
||||
* information about nodes location in file.
|
||||
*/
|
||||
class AstNode {
|
||||
public:
|
||||
|
||||
/** Contains information about where in source file given node is located */
|
||||
Span span;
|
||||
|
||||
AstNode() = default;
|
||||
|
||||
virtual ~AstNode();
|
||||
|
||||
AstNode(AstNode &&) = default;
|
||||
|
||||
AstNode &operator=(AstNode &&) = default;
|
||||
|
||||
AstNode(const AstNode &) = default;
|
||||
|
||||
AstNode &operator=(const AstNode &) = default;
|
||||
};
|
||||
|
||||
/**
|
||||
* AST base enum class,
|
||||
* Used to represent AST enums
|
||||
* */
|
||||
template<typename T>
|
||||
struct EnumNode : public AstNode {
|
||||
EnumNode() = default;
|
||||
|
@ -39,284 +41,416 @@ struct EnumNode : public AstNode {
|
|||
T value;
|
||||
};
|
||||
|
||||
/** Represents string
|
||||
* value contains quote-marks ("" or '' depending on string type)
|
||||
* */
|
||||
struct StringNode : public AstNode {
|
||||
/** String including quote-marks*/
|
||||
std::string value;
|
||||
|
||||
/** Returns string without quote-marks */
|
||||
std::string asString();
|
||||
};
|
||||
|
||||
/** Represents identifiers */
|
||||
struct IdentifierNode : public AstNode {
|
||||
std::string value;
|
||||
};
|
||||
|
||||
/** Represents all numbers used
|
||||
* All numbers must fit into long long int
|
||||
* */
|
||||
struct NumberNode : public AstNode {
|
||||
long long int value;
|
||||
long long int value = 0;
|
||||
|
||||
explicit NumberNode(const std::string &expression);
|
||||
|
||||
NumberNode() : value(0) {}
|
||||
NumberNode() = default;
|
||||
};
|
||||
|
||||
/** Represents color
|
||||
* color comes in two formats #RRGGBB or #RRGGBBAA (AA representing opacity)
|
||||
* */
|
||||
struct ColorNode : public AstNode {
|
||||
Color color;
|
||||
|
||||
explicit ColorNode(const std::string &expression);
|
||||
|
||||
ColorNode() {}
|
||||
ColorNode() = default;
|
||||
};
|
||||
|
||||
|
||||
struct CountNode : public AstNode {
|
||||
/** Represents ordered number pair */
|
||||
struct NumberPairNode : public AstNode {
|
||||
NumberNode first;
|
||||
NumberNode second;
|
||||
|
||||
CountNode(NumberNode first, NumberNode second) : first(std::move(first)), second(std::move(second)) {}
|
||||
NumberPairNode(NumberNode first, NumberNode second) : first(first), second(second) {}
|
||||
|
||||
CountNode() = default;
|
||||
};
|
||||
|
||||
|
||||
struct AddressSpaceNode : public AstNode {
|
||||
IdentifierNode name;
|
||||
NumberNode start;
|
||||
NumberNode end;
|
||||
NumberPairNode() = default;
|
||||
};
|
||||
|
||||
/** Represents generic value
|
||||
* Because attributes can contain different value types,
|
||||
* this allows us to use one generic type for all attributes
|
||||
* */
|
||||
class ValueNode : public AstNode {
|
||||
public:
|
||||
enum ValueType {
|
||||
/** Stores same content as NumberNode */
|
||||
INT,
|
||||
/** Stores same content as StringNode */
|
||||
STRING,
|
||||
/** Stores true or false */
|
||||
BOOL,
|
||||
/** Stores wire nam or null */
|
||||
WIRE,
|
||||
/** Default type assigned when node value is of type IdentifierNode and more correct type is assigned later */
|
||||
IDENTIFIER,
|
||||
/** Stores memory name or null */
|
||||
MEMORY,
|
||||
/** Stores null */
|
||||
NIL,
|
||||
/** Store same content as ColorNode */
|
||||
COLOR,
|
||||
};
|
||||
|
||||
private:
|
||||
EnumNode<ValueType> type;
|
||||
std::optional<long long> intValue;
|
||||
std::optional<std::string> stringValue;
|
||||
std::optional<bool> boolValue;
|
||||
std::optional<std::string> identifierValue;
|
||||
std::optional<Color> colorValue;
|
||||
/** Type determines what is stored inside ValueNode */
|
||||
EnumNode<ValueType> type = EnumNode(NIL);
|
||||
/** All possible values for ValueNode are stored inside optionals */
|
||||
std::optional<long long> intValue = std::nullopt;
|
||||
std::optional<std::string> stringValue = std::nullopt;
|
||||
std::optional<bool> boolValue = std::nullopt;
|
||||
std::optional<std::string> identifierValue = std::nullopt;
|
||||
std::optional<Color> colorValue = std::nullopt;
|
||||
|
||||
public:
|
||||
ValueNode() = default;
|
||||
|
||||
ValueType getType() const {
|
||||
return type.value;
|
||||
}
|
||||
|
||||
long long asInt();
|
||||
ValueType getType() const;
|
||||
|
||||
/** Checks ValueNode is of requested type and returns it or returns default value for given type*/
|
||||
long long int asInt();
|
||||
std::string asString();
|
||||
|
||||
std::string asIdentifier();
|
||||
|
||||
Color asColor();
|
||||
|
||||
bool asBool();
|
||||
|
||||
/** Returns true if ValueNode is of given valueType */
|
||||
bool is(ValueType valueType);
|
||||
|
||||
/** Static methods used to generate ValueNodes of requested type */
|
||||
static ValueNode ofBool(bool _value);
|
||||
|
||||
static ValueNode ofInt(long long _value);
|
||||
|
||||
static ValueNode ofString(std::string _value);
|
||||
|
||||
static ValueNode ofIdentifier(std::string _value);
|
||||
|
||||
static ValueNode ofMemory(std::optional<std::string> _value);
|
||||
|
||||
static ValueNode ofNull();
|
||||
|
||||
static ValueNode ofColor(Color color);
|
||||
|
||||
static ValueNode ofWire(std::optional<std::string> _value);
|
||||
|
||||
};
|
||||
|
||||
/** Represents an identifier-value pair*/
|
||||
struct PropertyNode : public AstNode {
|
||||
IdentifierNode key;
|
||||
ValueNode value;
|
||||
|
||||
PropertyNode() = default;
|
||||
PropertyNode(IdentifierNode key, ValueNode value): key(key), value(value) {}
|
||||
};
|
||||
|
||||
/** Represents a string-value pair */
|
||||
struct StringPropertyNode : public AstNode {
|
||||
StringNode key;
|
||||
ValueNode value;
|
||||
|
||||
StringPropertyNode() = default;
|
||||
StringPropertyNode(StringNode key, ValueNode value): key(key), value(value) {}
|
||||
};
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* RULE TYPES *
|
||||
*****************************************************************************/
|
||||
|
||||
struct IfStatementNode;
|
||||
|
||||
/** Represents validation rule
|
||||
* Rules are made from a list of
|
||||
* if - else if statements
|
||||
* */
|
||||
struct RuleNode : public AstNode {
|
||||
std::vector<IfStatementNode> statements;
|
||||
};
|
||||
|
||||
/** Represents condition inside if statement
|
||||
* Every condition is made from optional negation operator !
|
||||
* Function called and list of function parameters
|
||||
* */
|
||||
struct ConditionNode {
|
||||
bool negated;
|
||||
IdentifierNode functionName;
|
||||
std::vector<ValueNode> params;
|
||||
};
|
||||
|
||||
class ActionNode : public AstNode {
|
||||
public:
|
||||
/** Represents action executed inside if statement
|
||||
* */
|
||||
struct ActionNode : public AstNode {
|
||||
/** There are two types of action determined by action type */
|
||||
enum ActionType {
|
||||
/** Error actions represent invalid state and cause validation to fail */
|
||||
ERROR,
|
||||
/** Warning actions represent states that can cause issue when simulating
|
||||
* model but models created with it are still valid
|
||||
* */
|
||||
WARNING
|
||||
};
|
||||
|
||||
EnumNode<ActionType> type;
|
||||
/** Message used if condition is fulfilled */
|
||||
StringNode message;
|
||||
};
|
||||
|
||||
|
||||
/** If statements represents one validation check inside rule */
|
||||
struct IfStatementNode : public AstNode {
|
||||
ConditionNode condition;
|
||||
ActionNode action;
|
||||
};
|
||||
|
||||
struct RuleNode : public AstNode {
|
||||
std::vector<IfStatementNode> statements;
|
||||
};
|
||||
|
||||
struct EnumerationNode : public AstNode {
|
||||
StringNode key;
|
||||
ValueNode value;
|
||||
};
|
||||
/*****************************************************************************
|
||||
* ATTRIBUTE TYPES *
|
||||
*****************************************************************************/
|
||||
|
||||
/** Represents popup dialog used to modified attribute inside which it is defined
|
||||
* */
|
||||
struct PopupNode : public AstNode {
|
||||
/** Determines type of popup*/
|
||||
enum PopupType {
|
||||
/** Automatic popup is opened when component or connection containing it is defined */
|
||||
AUTOMATIC,
|
||||
/** On demand popups are opened on user request usually from context menus*/
|
||||
ON_DEMAND
|
||||
};
|
||||
|
||||
std::optional<EnumNode<PopupType>> type;
|
||||
/** Title of popup */
|
||||
std::optional<StringNode> title;
|
||||
/** Text of popup */
|
||||
std::optional<StringNode> text;
|
||||
|
||||
/** If popup contains an enumeration*/
|
||||
bool enumerated;
|
||||
std::vector<EnumerationNode> enumeration;
|
||||
std::vector<StringPropertyNode> enumeration;
|
||||
|
||||
/** Validation rules for given popup */
|
||||
std::vector<RuleNode> rules;
|
||||
};
|
||||
|
||||
struct PropertyNode : public AstNode {
|
||||
IdentifierNode key;
|
||||
ValueNode value;
|
||||
/** Represents component or connection attribute
|
||||
* Attributes are values that can programmatically be changed
|
||||
* if popup is defined
|
||||
* */
|
||||
struct AttributeNode : public AstNode {
|
||||
/** Type of attribute */
|
||||
ValueNode::ValueType type;
|
||||
/** Name of attribute */
|
||||
IdentifierNode name;
|
||||
/** Default type of attribute */
|
||||
std::optional<ValueNode> defaultValue;
|
||||
/** Popup used to change attribute value */
|
||||
std::optional<PopupNode> popup;
|
||||
};
|
||||
|
||||
struct DisplayItemNode : public AstNode {
|
||||
IdentifierNode type;
|
||||
std::vector<PropertyNode> values;
|
||||
/*****************************************************************************
|
||||
* DISPLAY TYPES *
|
||||
*****************************************************************************/
|
||||
|
||||
long long int asInt(std::vector<SourceError> *errors, const std::string &property, long long int _default = 0) {
|
||||
for (auto &prop: values) {
|
||||
if (prop.key.value == property) {
|
||||
if (prop.value.is(ValueNode::INT)) {
|
||||
return prop.value.asInt();
|
||||
} else {
|
||||
if (errors != nullptr) {
|
||||
errors->emplace_back(prop.value.span, "expected number");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return _default;
|
||||
}
|
||||
|
||||
Color asColor(std::vector<SourceError> *errors, const std::string &property, Color _default = Color(0, 0, 0)) {
|
||||
for (auto &prop: values) {
|
||||
if (prop.key.value == property) {
|
||||
if (prop.value.is(ValueNode::COLOR)) {
|
||||
return prop.value.asColor();
|
||||
} else {
|
||||
if (errors != nullptr) {
|
||||
errors->emplace_back(prop.value.span, "expected number");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return _default;
|
||||
}
|
||||
|
||||
std::string asIdentifier(std::vector<SourceError> *errors, const std::string &property, std::string _default = "") {
|
||||
for (auto &prop: values) {
|
||||
if (prop.key.value == property) {
|
||||
if (prop.value.is(ValueNode::IDENTIFIER)) {
|
||||
return prop.value.asIdentifier();
|
||||
} else {
|
||||
if (errors != nullptr) {
|
||||
errors->emplace_back(prop.value.span, "expected identifier");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return _default;
|
||||
}
|
||||
|
||||
|
||||
std::string asString(std::vector<SourceError> *errors, const std::string &property, std::string _default = "") {
|
||||
for (auto &prop: values) {
|
||||
if (prop.key.value == property) {
|
||||
if (prop.value.is(ValueNode::STRING)) {
|
||||
return prop.value.asString();
|
||||
} else {
|
||||
if (errors != nullptr) {
|
||||
errors->emplace_back(prop.value.span, "expected string");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return _default;
|
||||
}
|
||||
};
|
||||
struct DisplayItemNode;
|
||||
|
||||
/** Represents how a component or bus is rendered
|
||||
* Display is made from an list of display items
|
||||
* */
|
||||
struct DisplayNode : public AstNode {
|
||||
std::vector<DisplayItemNode> items;
|
||||
};
|
||||
|
||||
struct PinConnectionNode : public AstNode {
|
||||
enum ConnectionType {
|
||||
REQUIRED,
|
||||
OPTIONAL
|
||||
};
|
||||
/** DisplayItem represents one rendered item
|
||||
* in source code items are defined similar to json objects
|
||||
* eg.
|
||||
* @code rect {
|
||||
* x: 100;
|
||||
* y: 100;
|
||||
* w: 100;
|
||||
* h: 100;
|
||||
* fillColor: #123456
|
||||
* }
|
||||
* */
|
||||
struct DisplayItemNode : public AstNode {
|
||||
/** Contains type of display item */
|
||||
IdentifierNode type;
|
||||
/** Contains all property nodes */
|
||||
std::vector<PropertyNode> values;
|
||||
|
||||
StringNode message;
|
||||
EnumNode<ConnectionType> type;
|
||||
/** Returns value of requested property
|
||||
* If requested property doesn't exists default value is returned (eg. asInt is called but PropertyNode contains string)
|
||||
* If value of requested property is different than expected nullopt is retured
|
||||
* */
|
||||
std::optional<long long int> asInt(const std::string &property, long long int _default = 0);
|
||||
std::optional<Color> asColor(const std::string &property, Color _default = Color(0, 0, 0));
|
||||
std::optional<std::string> asString(const std::string &property, std::string _default = "");
|
||||
|
||||
private:
|
||||
std::optional<PropertyNode> getProperty(const std::string &property);
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* LIBRARY TYPES *
|
||||
*****************************************************************************/
|
||||
|
||||
/** Represents AddressSpaces
|
||||
* Address spaces are defined with their name and address range
|
||||
* */
|
||||
struct AddressSpaceNode : public AstNode {
|
||||
IdentifierNode name;
|
||||
/** Range represent which addresses are available for components that use memory space [first, second> */
|
||||
NumberPairNode range;
|
||||
};
|
||||
|
||||
/** Pins are used to create component-component or component-bus connections */
|
||||
struct PinNode : public AstNode {
|
||||
/** Determines pin type, pin types currently only affect how pins are rendered */
|
||||
enum PinType {
|
||||
IN_OUT,
|
||||
IN,
|
||||
OUT
|
||||
};
|
||||
|
||||
/** Name of pin */
|
||||
IdentifierNode name;
|
||||
/** Type of pin */
|
||||
EnumNode<PinType> type;
|
||||
/** Tooltip content displayed on hover over pin */
|
||||
std::optional<StringNode> tooltip;
|
||||
std::optional<PinConnectionNode> connection;
|
||||
/** If present this means pin must be connected to another component or bus to create connection
|
||||
* Connection contains error message shown
|
||||
* */
|
||||
std::optional<StringNode> connection;
|
||||
/** Determines how the pin is displayed */
|
||||
std::optional<DisplayNode> display;
|
||||
/** If pin connection is optional it requires list of wires used to populate comdel model */
|
||||
std::optional<std::vector<ValueNode>> wires;
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents COMDEL component
|
||||
* */
|
||||
struct ComponentNode : public AstNode {
|
||||
/** Determines type of component */
|
||||
enum ComponentType {
|
||||
/** Generic component */
|
||||
OTHER,
|
||||
/** Represents processor, all processors have implicit attribute _memory if type memory
|
||||
* used when generating COMDEL model to connect memories and processors
|
||||
*/
|
||||
PROCESSOR,
|
||||
/** Represents memory, all components of type memory can be selected in _memory attribute of processor */
|
||||
MEMORY
|
||||
};
|
||||
|
||||
/** Component name */
|
||||
IdentifierNode name;
|
||||
/** Tooltip displayed on hover */
|
||||
std::optional<StringNode> tooltip;
|
||||
/** Contains path to COMDEL source containing current component */
|
||||
std::optional<StringNode> source;
|
||||
/** Type of component */
|
||||
EnumNode<ComponentType> type;
|
||||
/** List of component level rules */
|
||||
std::vector<RuleNode> rules;
|
||||
/** Default used to name instances */
|
||||
std::optional<IdentifierNode> instanceName;
|
||||
/** Count determines number of instances allowed in a schema */
|
||||
std::optional<NumberPairNode> count;
|
||||
/** Display determines how component is rendered */
|
||||
std::optional<DisplayNode> display;
|
||||
/** List of all pins */
|
||||
std::vector<PinNode> pins;
|
||||
/** List of all attributes */
|
||||
std::vector<AttributeNode> attributes;
|
||||
};
|
||||
|
||||
/** WireNode represents COMDEL wire
|
||||
* */
|
||||
struct WireNode : public AstNode {
|
||||
/** Determines type of wires */
|
||||
enum WireType {
|
||||
/** Generic wire */
|
||||
WIRE,
|
||||
/** wired_and can have multiple sources, that are ANDed together */
|
||||
WIRED_AND,
|
||||
/** wired_and can have multiple sources, that are ORed together */
|
||||
WIRED_OR,
|
||||
/** r_wire can remain unconnected */
|
||||
R_WIRE
|
||||
};
|
||||
EnumNode<WireType> type;
|
||||
/** Name of wire */
|
||||
IdentifierNode name;
|
||||
/** Number of bits inside of a wire */
|
||||
NumberNode size;
|
||||
|
||||
/** If wire is visible or hidden, this determines how wires are generated in COMDEL */
|
||||
bool hidden = false;
|
||||
|
||||
/** If wire isn't connected to anything it is replaced with terminate with terminateWith value */
|
||||
bool hasTerminateWith;
|
||||
ValueNode terminateWith;
|
||||
};
|
||||
|
||||
struct AttributeNode : public AstNode {
|
||||
ValueNode::ValueType type;
|
||||
/** Buses dont exist in COMDEL but they are useful
|
||||
* as they allow us to connect multiple COMDEL wires together
|
||||
* */
|
||||
struct BusNode : public AstNode {
|
||||
enum BusType {
|
||||
/** This busses connect two components */
|
||||
AUTOMATIC,
|
||||
/**
|
||||
* This busses allow us to connect multiple component together using one bus
|
||||
* */
|
||||
REGULAR,
|
||||
/** This busses connect two components,
|
||||
* they differ from automatic as they allow us to connect same pins multiple times */
|
||||
SINGLE_AUTOMATIC
|
||||
};
|
||||
|
||||
EnumNode<BusType> type;
|
||||
IdentifierNode name;
|
||||
std::optional<ValueNode> defaultValue;
|
||||
std::optional<PopupNode> popup;
|
||||
/** Default used to name instances */
|
||||
std::optional<IdentifierNode> instanceName;
|
||||
/** Tooltip displayed on hover */
|
||||
std::optional<StringNode> tooltip;
|
||||
/** Count determines number of instances allowed in a schema */
|
||||
std::optional<NumberPairNode> count;
|
||||
/** Display determines how component is rendered */
|
||||
std::optional<DisplayNode> display;
|
||||
|
||||
/** List of all COMDEL wires contained in bus */
|
||||
std::vector<WireNode> wires;
|
||||
};
|
||||
|
||||
/** Represents ComponentConnection key in Connection node
|
||||
* (eg. componentName.pinName)
|
||||
* */
|
||||
struct ConnectionComponentNode : public AstNode {
|
||||
IdentifierNode component;
|
||||
IdentifierNode pin;
|
||||
};
|
||||
|
||||
/** Represents Connection node
|
||||
* Connection can be between component and bus in which second is null,
|
||||
* or between two components
|
||||
* */
|
||||
struct ConnectionNode : public AstNode {
|
||||
ConnectionComponentNode first;
|
||||
std::optional<ConnectionComponentNode> second;
|
||||
|
@ -324,51 +458,22 @@ struct ConnectionNode : public AstNode {
|
|||
IdentifierNode bus;
|
||||
std::vector<AttributeNode> attributes;
|
||||
|
||||
/** If connection is of type component-component it contains two pairs of wires */
|
||||
std::vector<ValueNode> firstWires;
|
||||
std::optional<std::vector<ValueNode>> secondWires;
|
||||
};
|
||||
|
||||
struct ComponentNode : public AstNode {
|
||||
enum ComponentType {
|
||||
OTHER,
|
||||
PROCESSOR,
|
||||
MEMORY
|
||||
};
|
||||
|
||||
IdentifierNode name;
|
||||
std::optional<StringNode> tooltip;
|
||||
std::optional<StringNode> source;
|
||||
EnumNode<ComponentType> type;
|
||||
std::vector<RuleNode> rules;
|
||||
std::optional<IdentifierNode> instanceName;
|
||||
std::optional<CountNode> count;
|
||||
std::optional<DisplayNode> display;
|
||||
std::vector<PinNode> pins;
|
||||
std::vector<AttributeNode> attributes;
|
||||
};
|
||||
|
||||
struct BusNode : public AstNode {
|
||||
enum BusType {
|
||||
AUTOMATIC,
|
||||
REGULAR,
|
||||
SINGLE_AUTOMATIC
|
||||
};
|
||||
|
||||
EnumNode<BusType> type;
|
||||
IdentifierNode name;
|
||||
std::optional<IdentifierNode> instanceName;
|
||||
std::optional<StringNode> tooltip;
|
||||
std::optional<CountNode> count;
|
||||
std::optional<DisplayNode> display;
|
||||
|
||||
std::vector<WireNode> wires;
|
||||
};
|
||||
|
||||
/** LibraryNode represent library instance */
|
||||
struct LibraryNode : public AstNode {
|
||||
/** Name of library */
|
||||
std::optional<StringNode> name;
|
||||
/** Library info contains generic information about library */
|
||||
std::optional<StringNode> libraryInfo;
|
||||
/** Contains text that is added to top of COMDEL file */
|
||||
std::optional<StringNode> header;
|
||||
/** Contains path to component directory */
|
||||
std::optional<StringNode> componentDirectory;
|
||||
/** Contains text that is added to top of System component in COMDEL file */
|
||||
std::optional<StringNode> componentHeader;
|
||||
|
||||
std::vector<AddressSpaceNode> addressSpaces;
|
||||
|
@ -377,46 +482,64 @@ struct LibraryNode : public AstNode {
|
|||
std::vector<BusNode> buses;
|
||||
std::vector<ConnectionNode> connections;
|
||||
|
||||
/** Contains properties used to translate dialog and error messages */
|
||||
std::vector<PropertyNode> messages;
|
||||
};
|
||||
|
||||
// SCHEMA models
|
||||
/*****************************************************************************
|
||||
* LIBRARY TYPES *
|
||||
*****************************************************************************/
|
||||
|
||||
/** Represents instance of attribute in component or connection instance */
|
||||
struct InstanceAttributeNode : public AstNode {
|
||||
IdentifierNode name;
|
||||
ValueNode value;
|
||||
};
|
||||
|
||||
/** Represents instance of a component or a bus */
|
||||
struct InstanceNode : public AstNode {
|
||||
/** Contains instance name */
|
||||
IdentifierNode name;
|
||||
/** Contains component name */
|
||||
IdentifierNode component;
|
||||
|
||||
std::optional<CountNode> position;
|
||||
/** Contains position of component instance */
|
||||
std::optional<NumberPairNode> position;
|
||||
std::vector<InstanceAttributeNode> attributes;
|
||||
|
||||
/** Contains size of bus instances */
|
||||
std::optional<NumberNode> size;
|
||||
};
|
||||
|
||||
struct ConnectionComponentInstance : public AstNode {
|
||||
/** Represents ComponentConnection of a selected instance */
|
||||
struct ConnectionComponentInstanceNode : public AstNode {
|
||||
/** Name of component instance */
|
||||
IdentifierNode instance;
|
||||
/** Name of pin */
|
||||
IdentifierNode pin;
|
||||
};
|
||||
|
||||
/** Represents Connection instance */
|
||||
struct ConnectionInstanceNode : public AstNode {
|
||||
ConnectionComponentInstance first;
|
||||
std::optional<ConnectionComponentInstance> second;
|
||||
ConnectionComponentInstanceNode first;
|
||||
std::optional<ConnectionComponentInstanceNode> second;
|
||||
|
||||
IdentifierNode bus;
|
||||
|
||||
std::vector<InstanceAttributeNode> attributes;
|
||||
};
|
||||
|
||||
|
||||
/** Represent schema instance */
|
||||
struct SchemaNode : public AstNode {
|
||||
/** Contains path to library source */
|
||||
std::optional<StringNode> source;
|
||||
|
||||
/** Contains list of instances */
|
||||
std::vector<InstanceNode> instances;
|
||||
/** Contains list of connection */
|
||||
std::vector<ConnectionInstanceNode> connections;
|
||||
|
||||
/** Contains library */
|
||||
std::optional<LibraryNode> library;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
//
|
||||
// Created by bbr on 12.06.22..
|
||||
//
|
||||
|
||||
#include "color.h"
|
|
@ -7,12 +7,12 @@
|
|||
|
||||
|
||||
struct Color {
|
||||
unsigned char r;
|
||||
unsigned char g;
|
||||
unsigned char b;
|
||||
unsigned char a;
|
||||
unsigned char r = 0;
|
||||
unsigned char g = 0;
|
||||
unsigned char b = 0;
|
||||
unsigned char a = 255;
|
||||
|
||||
Color(): r(0), g(0), b(0), a(0) {}
|
||||
Color() = default;
|
||||
|
||||
Color(unsigned char r, unsigned char g, unsigned char b, unsigned char a = 0): r(r), g(g), b(b), a(a) {}
|
||||
};
|
||||
|
|
|
@ -11,11 +11,14 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
/** Contains results of tokenizing,
|
||||
* if errors isn't empty tokenizing has failed */
|
||||
struct LexerResult {
|
||||
std::vector<Token> tokens;
|
||||
std::vector<SourceError> errors;
|
||||
};
|
||||
|
||||
/** Used to tokenize input string */
|
||||
class ComdelLexer {
|
||||
|
||||
enum Radix {
|
||||
|
@ -24,9 +27,11 @@ class ComdelLexer {
|
|||
HEX_NUMBER = 16
|
||||
};
|
||||
|
||||
/** Source file */
|
||||
std::string source;
|
||||
std::vector<Token> tokens;
|
||||
std::vector<SourceError> errors;
|
||||
/** Source file */
|
||||
ParseContext *parseContext;
|
||||
unsigned fileId;
|
||||
|
||||
|
@ -36,34 +41,32 @@ public:
|
|||
LexerResult tokenize();
|
||||
|
||||
private:
|
||||
void skipWhitespace();
|
||||
|
||||
unsigned takeNumberInRadix(Radix radix);
|
||||
|
||||
unsigned takeHexColor();
|
||||
|
||||
bool digitIsValid(char ch, Radix radix);
|
||||
|
||||
Radix takeRadix();
|
||||
|
||||
PResult<TokenType> nextTokenType();
|
||||
|
||||
/** Current parsing info */
|
||||
Position tokenBegin;
|
||||
Position position;
|
||||
char ch;
|
||||
|
||||
/** Methods used to skip unused content */
|
||||
void skipWhitespace();
|
||||
void skipComment();
|
||||
|
||||
bool skipMultilineComment();
|
||||
void bump(unsigned count = 1);
|
||||
|
||||
/** Metods used for number parsing */
|
||||
unsigned takeNumberInRadix(Radix radix);
|
||||
bool digitIsValid(char ch, Radix radix);
|
||||
Radix takeRadix();
|
||||
|
||||
unsigned takeHexColor();
|
||||
|
||||
PResult<TokenType> nextTokenType();
|
||||
|
||||
PResult<TokenType> takeString();
|
||||
|
||||
PResult<TokenType> takeRawString();
|
||||
|
||||
void bump(unsigned count = 1);
|
||||
|
||||
char peek();
|
||||
|
||||
/** Checks if we reached end of file */
|
||||
bool eof();
|
||||
};
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -42,16 +42,20 @@ private:
|
|||
|
||||
Span &getPreviousSpan();
|
||||
|
||||
/** Skips current token */
|
||||
void bump();
|
||||
|
||||
/** Checks if next token is of given type and if it is consumes it */
|
||||
bool consume(TokenType tokenType);
|
||||
|
||||
/** Checks if next token is of given type */
|
||||
bool check(TokenType tokenType);
|
||||
|
||||
/** Skips until next keyword on same level
|
||||
* Used to continue parsing on error
|
||||
* */
|
||||
void skipUntilNextKeyword();
|
||||
|
||||
/** Retuns current token */
|
||||
Token ¤t();
|
||||
|
||||
/** Throws error of unexpected types */
|
||||
[[nodiscard]] PError unexpected();
|
||||
|
||||
template<typename T>
|
||||
|
@ -63,73 +67,45 @@ private:
|
|||
|
||||
Spanner getSpanner();
|
||||
|
||||
// used to parse library and schema
|
||||
/** Base types */
|
||||
PResult<StringNode> parseString();
|
||||
|
||||
PResult<ColorNode> parseColor();
|
||||
|
||||
PResult<IdentifierNode> parseIdentifier();
|
||||
|
||||
PResult<NumberNode> parseNumber();
|
||||
|
||||
PResult<CountNode> parseCount();
|
||||
|
||||
PResult<NumberPairNode> parseNumberPair();
|
||||
PResult<PropertyNode> parseProperty(std::optional<TokenType> valueType);
|
||||
|
||||
PResult<EnumerationNode> parseEnumeration();
|
||||
|
||||
PResult<ValueNode> parseConnectionWire();
|
||||
|
||||
PResult<ComponentNode> parseComponent();
|
||||
|
||||
PResult<AddressSpaceNode> parseAddress();
|
||||
|
||||
PResult<PinNode> parsePin();
|
||||
|
||||
PResult<DisplayNode> parseDisplay();
|
||||
|
||||
PResult<PinConnectionNode> parsePinConnection();
|
||||
|
||||
PResult<AttributeNode> parseAttribute();
|
||||
|
||||
PResult<PopupNode> parsePopup();
|
||||
|
||||
PResult<RuleNode> parseRule();
|
||||
|
||||
PResult<BusNode> parseBus();
|
||||
|
||||
PResult<WireNode> parseWire();
|
||||
|
||||
PResult<ConnectionNode> parseConnection();
|
||||
|
||||
PResult<DisplayItemNode> parseDisplayItem();
|
||||
|
||||
PResult<IfStatementNode> parseIfStatement();
|
||||
|
||||
PResult<StringPropertyNode> parseStringProperty();
|
||||
PResult<ValueNode> parseValue();
|
||||
|
||||
// used to parse schema
|
||||
PResult<CountNode> parsePosition();
|
||||
|
||||
PResult<InstanceNode> parseInstance();
|
||||
|
||||
PResult<InstanceAttributeNode> parseInstanceAttribute();
|
||||
|
||||
PResult<ConnectionInstanceNode> parseConnectionInstance();
|
||||
|
||||
/** Library types */
|
||||
PResult<ValueNode> parseConnectionWire();
|
||||
PResult<ComponentNode> parseComponent();
|
||||
PResult<EnumNode<ComponentNode::ComponentType>> parseComponentType();
|
||||
|
||||
PResult<AddressSpaceNode> parseAddress();
|
||||
PResult<PinNode> parsePin();
|
||||
PResult<DisplayNode> parseDisplay();
|
||||
PResult<AttributeNode> parseAttribute();
|
||||
PResult<PopupNode> parsePopup();
|
||||
PResult<RuleNode> parseRule();
|
||||
PResult<BusNode> parseBus();
|
||||
PResult<WireNode> parseWire();
|
||||
PResult<ConnectionNode> parseConnection();
|
||||
PResult<ConnectionComponentNode> parseConnectionComponent();
|
||||
PResult<DisplayItemNode> parseDisplayItem();
|
||||
PResult<IfStatementNode> parseIfStatement();
|
||||
PResult<EnumNode<BusNode::BusType>> parseBusType();
|
||||
|
||||
PResult<EnumNode<PinConnectionNode::ConnectionType>> parseConnectionType();
|
||||
/** Schema types */
|
||||
PResult<InstanceNode> parseInstance();
|
||||
PResult<InstanceAttributeNode> parseInstanceAttribute();
|
||||
PResult<ConnectionInstanceNode> parseConnectionInstance();
|
||||
PResult<ConnectionComponentInstanceNode> parseConnectionComponentInstance();
|
||||
|
||||
public:
|
||||
explicit ComdelParser(std::vector<Token> tokens);
|
||||
|
||||
std::optional<SchemaNode> parseSchema();
|
||||
|
||||
std::optional<LibraryNode> parseLibrary();
|
||||
|
||||
const std::vector<SourceError> &getErrors();
|
||||
};
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
/*** Represent source file */
|
||||
class SourceFile {
|
||||
std::string fileName;
|
||||
std::string source;
|
||||
|
@ -22,7 +23,7 @@ public:
|
|||
void addLineOffset(unsigned offset);
|
||||
};
|
||||
|
||||
|
||||
/*** Represent parsing context */
|
||||
class ParseContext {
|
||||
std::string applicationDir;
|
||||
std::vector<SourceFile> fileMap;
|
||||
|
|
|
@ -101,7 +101,6 @@ enum class TokenType {
|
|||
KW_SCHEMA,
|
||||
KW_POSITION,
|
||||
KW_SIZE,
|
||||
KW_UNKNOWN,
|
||||
|
||||
// TYPES
|
||||
INT_TYPE,
|
||||
|
|
|
@ -60,7 +60,7 @@
|
|||
}
|
||||
@pin glavniPin in {
|
||||
@tooltip "pin za spajanje na glavnu sabirnicu"
|
||||
@connection required("COMDEL se ne može stvoriti. FRISC nije spojen na sabirnicu")
|
||||
@connection "COMDEL se ne može stvoriti. FRISC nije spojen na sabirnicu"
|
||||
@display {
|
||||
pin {
|
||||
x: 42; y: 100; w: 16; h:16;
|
||||
|
@ -72,7 +72,6 @@
|
|||
|
||||
@pin memDirect inOut {
|
||||
@tooltip "pin za izravno spajanje na RAM"
|
||||
@connection optional("COMDEL se ne može stvoriti. FRISC nije spojen na sabirnicu")
|
||||
@display {
|
||||
pin {
|
||||
x: 100; y: 42; w: 16; h:16;
|
||||
|
@ -181,7 +180,7 @@
|
|||
|
||||
@pin glavniPin inOut {
|
||||
@tooltip "pin za spajanje na glavnu sabirnicu"
|
||||
@connection required("COMDEL se ne može stvoriti. Memorija nije spojena na sabirnicu")
|
||||
@connection "COMDEL se ne može stvoriti. Memorija nije spojena na sabirnicu"
|
||||
@display {
|
||||
/*
|
||||
pin {
|
||||
|
@ -204,7 +203,6 @@
|
|||
|
||||
@pin memDirect inOut {
|
||||
@tooltip "pin za spajanje na procesor"
|
||||
@connection optional("COMDEL se ne može stvoriti. Memorija nije spojena na sabirnicu")
|
||||
@display {
|
||||
/*
|
||||
pin {
|
||||
|
@ -276,7 +274,7 @@
|
|||
|
||||
@pin glavniPin in {
|
||||
@tooltip "pin za spajanje na glavnu sabirnicu"
|
||||
@connection required("COMDEL se ne može stvoriti. DMA nije spojena na sabirnicu")
|
||||
@connection "COMDEL se ne može stvoriti. DMA nije spojena na sabirnicu"
|
||||
@display {
|
||||
/*
|
||||
pin {
|
||||
|
@ -298,7 +296,6 @@
|
|||
|
||||
@pin dodatnaPoveznica in {
|
||||
@tooltip "pin za spajanje na pomocnu sabirnicu"
|
||||
@connection optional("COMDEL se ne može stvoriti. DMA nije spojen na nesto!")
|
||||
@display {
|
||||
pin {
|
||||
x: 100; y: 7; w: 16; h: 16;
|
||||
|
|
Loading…
Reference in New Issue