Token refactor

This commit is contained in:
Borna Rajkovic 2022-03-29 23:08:55 +02:00
parent 48e1c48579
commit 4c921759ef
6 changed files with 338 additions and 380 deletions

View File

@ -62,6 +62,8 @@ LexerResult ComdelLexer::tokenize() {
std::string text = source.substr(tokenBegin.offset,
position.offset - tokenBegin.offset);
tokenType = from_token(text, tokenType.value());
tokens.push_back(Token(*tokenType, Span(tokenBegin, position), text));
}

View File

@ -215,45 +215,34 @@ std::optional<Library> ComdelParser::parse()
while ( ! check(TokenType::END_OF_FILE) ) {
PResult<poly<AstNode>> err;
if (check(TokenType::KEYWORD)) {
auto keyword = KeywordType::determineType(current().text);
if(check(TokenType::KW_NAME)){
bump();
switch (keyword) {
case KeywordType::NAME:
ASSIGN_OR_SET_ERR(library.name, parseString());
break;
case KeywordType::HEADER:
} else if(check(TokenType::KW_HEADER)) {
bump();
ASSIGN_OR_SET_ERR(library.header, parseString());
break;
case KeywordType::DIRECTORY:
} else if(check(TokenType::KW_DIRECTORY)) {
bump();
ASSIGN_OR_SET_ERR(library.componentDirectory, parseString());
break;
case KeywordType::INFO:
} else if(check(TokenType::KW_INFO)) {
bump();
ASSIGN_OR_SET_ERR(library.libraryInfo, parseString());
break;
case KeywordType::ADDRESS:
} else if(check(TokenType::KW_ADDRESS)) {
APPEND_OR_SET_ERR(library.addressSpaces, parseAddress());
break;
case KeywordType::COMPONENT:
} else if(check(TokenType::KW_COMPONENT)) {
APPEND_OR_SET_ERR(library.components, parseComponent());
break;
case KeywordType::BUS:
} else if(check(TokenType::KW_BUS)) {
APPEND_OR_SET_ERR(library.buses, parseBus());
break;
case KeywordType::CONNECTION:
} else if(check(TokenType::KW_CONNECTION)) {
APPEND_OR_SET_ERR(library.connections, parseConnection());
break;
case KeywordType::MESSAGES:
} else if(check(TokenType::KW_MESSAGES)) {
bump();
ASSIGN_OR_SET_ERR(library.messages, parseList<PropertyNode>(std::optional<TokenType>(TokenType::LBRACE),
TokenType::RBRACE,
std::nullopt,
false,
[this]{return parseProperty(std::optional<TokenType>(TokenType::STRING));}
));
break;
default:
err = unexpected();
}
} else {
err = unexpected();
}
@ -324,30 +313,6 @@ PResult<NumberNode> ComdelParser::parseNumber()
}
/****************************************************************************
*
* Used for skipping block while testing
*
****************************************************************************/
void ComdelParser::parseBlock()
{
int depth = 0;
if(consume(TokenType::LBRACE)) {
depth++;
}
while(depth != 0) {
if(consume(TokenType::LBRACE)) {
depth++;
} else if(consume(TokenType::RBRACE)) {
depth--;
} else {
bump();
}
}
}
/****************************************************************************
*
* CountNode := "@size (" + NumberNode + "," + NumberNode + ")"
@ -356,6 +321,8 @@ void ComdelParser::parseBlock()
PResult<CountNode> ComdelParser::parseCount()
{
auto spanner = getSpanner();
RETURN_IF_NOT_TOKEN(TokenType::KW_COUNT);
RETURN_IF_NOT_TOKEN(TokenType::LPAREN);
auto first = parseNumber();
if(!first.has_value()) {
@ -383,22 +350,18 @@ PResult<PropertyNode> ComdelParser::parseProperty(std::optional<TokenType> value
ASSIGN_OR_RETURN_IF_ERR(key, parseIdentifier());
RETURN_IF_NOT_TOKEN(TokenType::COLON);
Value value;
if(valueType.has_value()) {
if(!check(*valueType)) {
if(valueType == TokenType::BOOL_TYPE) {
if(!(check(TokenType::TRUE) || check(TokenType::FALSE))) {
return unexpected();
}
} else if(!check(*valueType)) {
return unexpected();
}
}
if(check(TokenType::NUMBER)) {
value = Value::ofInt(parseNumber().value().value);
} else if(check(TokenType::STRING)) {
value = Value::ofString(parseString().value().value);
} else if(check(TokenType::IDENTIFIER)) {
value = Value::ofIdentifier(parseIdentifier().value().value);
} else {
return unexpected();
}
Value value;
ASSIGN_OR_RETURN_IF_ERR(value, parseValue());
RETURN_IF_NOT_TOKEN(TokenType::SEMICOLON);
@ -420,6 +383,8 @@ PResult<AddressSpace> ComdelParser::parseAddress()
AddressSpace addressSpace{};
RETURN_IF_NOT_TOKEN(TokenType::KW_ADDRESS);
ASSIGN_OR_RETURN_IF_ERR(addressSpace.name, parseIdentifier());
RETURN_IF_NOT_TOKEN(TokenType::LPAREN);
ASSIGN_OR_RETURN_IF_ERR(addressSpace.start, parseNumber());
@ -442,17 +407,16 @@ PResult<Component> ComdelParser::parseComponent()
Component component{};
RETURN_IF_NOT_TOKEN(TokenType::KW_COMPONENT);
ASSIGN_OR_RETURN_IF_ERR(component.name, parseIdentifier());
if(check(TokenType::IDENTIFIER)) {
auto tokenType = parseIdentifier();
if(tokenType.value().value == "processor") {
if(check(TokenType::CT_PROCESSOR)) {
bump();
component.type = Component::PROCESSOR;
} else if(tokenType.value().value == "memory") {
} else if(check(TokenType::CT_MEMORY)) {
bump();
component.type = Component::MEMORY;
} else {
return PError(SourceError{current().span, "expected 'processor' or 'memory'"});
}
} else {
component.type = Component::OTHER;
}
@ -461,37 +425,25 @@ PResult<Component> ComdelParser::parseComponent()
while(!check(TokenType::RBRACE)) {
PResult<poly<AstNode>> err;
if (check(TokenType::KEYWORD)) {
auto keyword = KeywordType::determineType(current().text);
if(check(TokenType::KW_INSTANCE_NAME)) {
bump();
switch (keyword) {
case KeywordType::INSTANCE_NAME:
ASSIGN_OR_RETURN_IF_ERR(component.instanceName, parseString());
break;
case KeywordType::TOOLTIP:
} else if(check(TokenType::KW_TOOLTIP)) {
bump();
ASSIGN_OR_RETURN_IF_ERR(component.tooltip, parseString());
break;
case KeywordType::SOURCE:
} else if(check(TokenType::KW_SOURCE)) {
bump();
ASSIGN_OR_RETURN_IF_ERR(component.source, parseString());
break;
case KeywordType::COUNT:
} else if(check(TokenType::KW_COUNT)) {
ASSIGN_OR_RETURN_IF_ERR(component.count, parseCount());
break;
case KeywordType::DISPLAY:
} else if(check(TokenType::KW_DISPLAY)) {
ASSIGN_OR_RETURN_IF_ERR(component.display, parseDisplay());
break;
case KeywordType::PIN:
} else if(check(TokenType::KW_PIN)) {
APPEND_OR_RETURN_IF_ERR(component.pin, parsePin());
break;
case KeywordType::ATTRIBUTE:
} else if(check(TokenType::KW_ATTRIBUTE)) {
APPEND_OR_RETURN_IF_ERR(component.attributes, parseAttribute());
break;
case KeywordType::RULE:
} else if(check(TokenType::KW_RULE)) {
APPEND_OR_RETURN_IF_ERR(component.rules, parseRule());
break;
default:
return unexpected();
}
} else {
return unexpected();
}
@ -510,6 +462,8 @@ PResult<Component> ComdelParser::parseComponent()
****************************************************************************/
PResult<Display> ComdelParser::parseDisplay() {
auto spanner = getSpanner();
RETURN_IF_NOT_TOKEN(TokenType::KW_DISPLAY);
Display display;
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
while(!check(TokenType::RBRACE)) {
@ -553,6 +507,8 @@ PResult<Bus> ComdelParser::parseBus() {
auto spanner = getSpanner();
Bus bus;
RETURN_IF_NOT_TOKEN(TokenType::KW_BUS);
ASSIGN_OR_RETURN_IF_ERR(bus.name, parseIdentifier());
if(check(TokenType::IDENTIFIER)) {
@ -571,20 +527,15 @@ PResult<Bus> ComdelParser::parseBus() {
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
while(!check(TokenType::RBRACE)) {
if (check(TokenType::KEYWORD)) {
auto keyword = KeywordType::determineType(current().text);
if(check(TokenType::KW_TOOLTIP)) {
bump();
switch (keyword) {
case KeywordType::TOOLTIP:
ASSIGN_OR_RETURN_IF_ERR(bus.tooltip, parseString());
break;
case KeywordType::COUNT:
} else if(check(TokenType::KW_COUNT)) {
ASSIGN_OR_RETURN_IF_ERR(bus.count, parseCount());
break;
case KeywordType::DISPLAY:
} else if(check(TokenType::KW_DISPLAY)) {
ASSIGN_OR_RETURN_IF_ERR(bus.display, parseDisplay());
break;
case KeywordType::WIRES:
} else if(check(TokenType::KW_WIRES)) {
bump();
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
while(check(TokenType::IDENTIFIER)) {
APPEND_OR_RETURN_IF_ERR(bus.wires, parseWire());
@ -594,10 +545,6 @@ PResult<Bus> ComdelParser::parseBus() {
}
}
RETURN_IF_NOT_TOKEN(TokenType::RBRACE);
break;
default:
return unexpected();
}
} else {
return unexpected();
}
@ -628,24 +575,21 @@ PResult<Wire> ComdelParser::parseWire() {
wire.size.value = 1;
}
if(check(TokenType::IDENTIFIER)) {
IdentifierNode identifier;
ASSIGN_OR_RETURN_IF_ERR(identifier, parseIdentifier());
if(identifier.value == "wire") {
// default
wire.type = Wire::WIRE;
} else if(identifier.value == "wired_and") {
if(check(TokenType::WIRE_DEFAULT)) {
bump();
wire.type = Wire::WIRE;
} else if(check(TokenType::WIRE_AND)) {
bump();
wire.type = Wire::WIRED_AND;
} else if(identifier.value == "wired_or") {
} else if(check(TokenType::WIRE_OR)) {
bump();
wire.type = Wire::WIRED_OR;
}else if(identifier.value == "r_wire") {
} else if(check(TokenType::R_WIRE)) {
bump();
wire.type = Wire::R_WIRE;
} else {
return PError(SourceError{current().span, "expected 'wire', 'wired_and', 'wired_or' or 'r_wire'"});
}
} else {
wire.type = Wire::WIRE;
}
return spanner(wire);
@ -664,43 +608,34 @@ PResult<Wire> ComdelParser::parseWire() {
PResult<Pin> ComdelParser::parsePin() {
auto spanner = getSpanner();
RETURN_IF_NOT_TOKEN(TokenType::KW_PIN);
Pin pin{};
ASSIGN_OR_RETURN_IF_ERR(pin.name, parseIdentifier());
if(check(TokenType::IDENTIFIER)) {
auto type = parseIdentifier();
if(type.value().value == "InOut") {
pin.type = Pin::IN_OUT;
} else if(type.value().value == "In") {
if(check(TokenType::PIN_IN)) {
bump();
pin.type = Pin::IN;
} else if(type.value().value == "Out") {
} else if(check(TokenType::PIN_OUT)) {
bump();
pin.type = Pin::OUT;
} else {
return PError(SourceError{type.value().span, "expected 'InOut', 'In', or 'Out'"});
}
} else {
} else if(check(TokenType::PIN_IN_OUT)) {
bump();
pin.type = Pin::IN_OUT;
} else {
return unexpected();
}
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
while(!check(TokenType::RBRACE)) {
if (check(TokenType::KEYWORD)) {
auto keyword = KeywordType::determineType(current().text);
if (check(TokenType::KW_TOOLTIP)) {
bump();
switch (keyword) {
case KeywordType::TOOLTIP:
ASSIGN_OR_RETURN_IF_ERR(pin.tooltip, parseString());
break;
case KeywordType::DISPLAY:
} else if (check(TokenType::KW_DISPLAY)) {
ASSIGN_OR_RETURN_IF_ERR(pin.display, parseDisplay());
break;
case KeywordType::CONNECTION:
} else if (check(TokenType::KW_CONNECTION)) {
ASSIGN_OR_RETURN_IF_ERR(pin.connection, parsePinConnection());
break;
default:
return unexpected();
}
} else {
return unexpected();
}
@ -721,11 +656,13 @@ PResult<PinConnection> ComdelParser::parsePinConnection() {
auto spanner = getSpanner();
PinConnection connection{};
RETURN_IF_NOT_TOKEN(TokenType::KW_CONNECTION);
if(check(TokenType::IDENTIFIER)) {
auto type = parseIdentifier();
if(type.value().value == "check_only") {
connection.type = PinConnection::CHECK_ONLY;
} else if(type.value().value == "In") {
} else if(type.value().value == "automatically") {
connection.type = PinConnection::AUTOMATICALLY;
} else {
return PError(SourceError{current().span, "expected identifiers 'check_only' or 'automatically'"});
@ -751,65 +688,57 @@ PResult<Attribute> ComdelParser::parseAttribute() {
auto spanner = getSpanner();
Attribute attribute;
RETURN_IF_NOT_TOKEN(TokenType::KW_ATTRIBUTE);
if(check(TokenType::IDENTIFIER)) {
ASSIGN_OR_RETURN_IF_ERR(attribute.name, parseIdentifier());
} else {
return unexpected();
}
if(check(TokenType::IDENTIFIER)) {
auto type = parseIdentifier();
if(type.value().value == "int") {
if(check(TokenType::INT_TYPE)) {
attribute.type = Value::INT;
} else if(type.value().value == "string") {
} else if(check(TokenType::STRING_TYPE)) {
attribute.type = Value::STRING;
} else if(type.value().value == "bool") {
} else if(check(TokenType::BOOL_TYPE)) {
attribute.type = Value::BOOL;
} else if(type.value().value == "wire") {
} else if(check(TokenType::WIRE_TYPE)) {
attribute.type = Value::IDENTIFIER;
} else {
return PError(SourceError{current().span, "expected type 'int', 'bool', 'string', 'wire'"});
}
} else {
return PError(SourceError{current().span, "expected type 'int', 'bool', 'string', 'wire'"});
}
if(!(check(TokenType::IDENTIFIER) && current().text == "default")) {
return PError(SourceError{current().span, "expected 'default'"});
return unexpected();
}
bump();
RETURN_IF_NOT_TOKEN(TokenType::DEFAULT);
if(attribute.type == Value::BOOL) {
IdentifierNode identifier;
ASSIGN_OR_RETURN_IF_ERR(identifier, parseIdentifier());
if(identifier.value == "true") {
if(check(TokenType::TRUE)) {
attribute.defaultValue = Value::ofBool(true);
} else if(identifier.value == "false") {
} else if(check(TokenType::FALSE)) {
attribute.defaultValue = Value::ofBool(false);
} else {
return PError(SourceError{current().span, "expected value 'true' or 'false'"});
return unexpected();
}
} else if(attribute.type == Value::INT) {
if(check(TokenType::NUMBER)) {
auto number = parseNumber();
attribute.defaultValue = Value::ofInt(number.value().value);
attribute.defaultValue = Value::ofInt(number->value);
} else {
return PError(SourceError{current().span, "expected number"});
return unexpected();
}
} else if(attribute.type == Value::STRING) {
if(check(TokenType::STRING)) {
auto string = parseString();
attribute.defaultValue = Value::ofString(string.value().value);
attribute.defaultValue = Value::ofString(string->value);
} else {
return PError(SourceError{current().span, "expected string"});
return unexpected();
}
} else if(attribute.type == Value::IDENTIFIER) {
if(check(TokenType::IDENTIFIER)) {
auto identifier = parseIdentifier();
attribute.defaultValue = Value::ofIdentifier(identifier.value().value);
attribute.defaultValue = Value::ofIdentifier(identifier->value);
} else {
return PError(SourceError{current().span, "expected wire"});
return unexpected();
}
}
@ -817,10 +746,9 @@ PResult<Attribute> ComdelParser::parseAttribute() {
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
Popup popup;
if(!(check(TokenType::KEYWORD) && current().text == "@popup")) {
return PError(SourceError{current().span, "expected '@popup'"});
if(!check(TokenType::KW_POPUP)) {
return unexpected();
}
bump();
ASSIGN_OR_RETURN_IF_ERR(popup, parsePopup());
attribute.popup = std::optional<Popup>(popup);
@ -838,19 +766,12 @@ PResult<Attribute> ComdelParser::parseAttribute() {
PResult<EnumerationNode> ComdelParser::parseEnumeration() {
auto spanner = getSpanner();
StringNode key;
ASSIGN_OR_RETURN_IF_ERR(key, parseString());
RETURN_IF_NOT_TOKEN(TokenType::EQUALS);
Value value;
if(check(TokenType::NUMBER)) {
value = Value::ofInt(parseNumber().value().value);
} else if(check(TokenType::STRING)) {
value = Value::ofString(parseString().value().value);
} else if(check(TokenType::IDENTIFIER)) {
value = Value::ofIdentifier(parseIdentifier().value().value);
} else {
return unexpected();
}
ASSIGN_OR_RETURN_IF_ERR(value, parseValue());
EnumerationNode node;
node.key = key;
@ -868,6 +789,8 @@ PResult<Popup> ComdelParser::parsePopup() {
auto spanner = getSpanner();
Popup popup;
RETURN_IF_NOT_TOKEN(TokenType::KW_POPUP);
if(check(TokenType::IDENTIFIER)) {
auto type = parseIdentifier();
if(type.value().value == "automatic") {
@ -884,21 +807,16 @@ PResult<Popup> ComdelParser::parsePopup() {
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
while(!check(TokenType::RBRACE)) {
PResult<poly<AstNode>> err;
if (check(TokenType::KEYWORD)) {
auto keyword = KeywordType::determineType(current().text);
if(check(TokenType::KW_TITLE)) {
bump();
switch (keyword) {
case KeywordType::TITLE:
ASSIGN_OR_RETURN_IF_ERR(popup.title, parseString());
break;
case KeywordType::TEXT:
} else if(check(TokenType::KW_TEXT)) {
bump();
ASSIGN_OR_RETURN_IF_ERR(popup.text, parseString());
break;
case KeywordType::RULE:
} else if(check(TokenType::KW_RULE)) {
APPEND_OR_RETURN_IF_ERR(popup.rules, parseRule());
break;
case KeywordType::ENUMERATED:
} else if(check(TokenType::KW_ENUMERATED)) {
bump();
popup.enumerated = true;
ASSIGN_OR_RETURN_IF_ERR(popup.enumeration,
parseList<EnumerationNode>(
@ -909,10 +827,6 @@ PResult<Popup> ComdelParser::parsePopup() {
[this]{ return parseEnumeration();}
)
);
break;
default:
return unexpected();
}
} else {
return unexpected();
}
@ -932,6 +846,8 @@ PResult<Connection> ComdelParser::parseConnection() {
auto spanner = getSpanner();
Connection connection;
RETURN_IF_NOT_TOKEN(TokenType::KW_CONNECTION);
RETURN_IF_NOT_TOKEN(TokenType::LPAREN);
ASSIGN_OR_RETURN_IF_ERR(connection.component, parseIdentifier());
RETURN_IF_NOT_TOKEN(TokenType::DOT);
@ -943,24 +859,14 @@ PResult<Connection> ComdelParser::parseConnection() {
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
while(!check(TokenType::RBRACE)) {
if (check(TokenType::KEYWORD)) {
auto keyword = KeywordType::determineType(current().text);
bump();
switch (keyword) {
case KeywordType::ATTRIBUTE:
if (check(TokenType::KW_ATTRIBUTE)) {
APPEND_OR_RETURN_IF_ERR(connection.attributes, parseAttribute());
break;
case KeywordType::WIRES:
{
} else if(check(TokenType::KW_WIRES)) {
bump();
auto wires = parseList<IdentifierNode>(std::optional<TokenType>(TokenType::LBRACE), TokenType::RBRACE, std::optional<TokenType>(TokenType::COMMA), false,
[this] { return parseIdentifier(); });
RETURN_IF_ERR(wires);
connection.wires = *wires;
}
break;
default:
return unexpected();
}
} else {
return unexpected();
}
@ -981,17 +887,16 @@ PResult<Rule> ComdelParser::parseRule() {
auto spanner = getSpanner();
Rule rule;
RETURN_IF_NOT_TOKEN(TokenType::KW_RULE);
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
while(!check(TokenType::RBRACE)) {
APPEND_OR_RETURN_IF_ERR(rule.statements, parseIfStatement());
if(check(TokenType::IDENTIFIER)) {
IdentifierNode node;
ASSIGN_OR_RETURN_IF_ERR(node, parseIdentifier());
if(node.value != "else") {
return PError(SourceError{node.span, "expected 'else'"});
}
if(check(TokenType::RBRACE)) {
break;
}
RETURN_IF_NOT_TOKEN(TokenType::ELSE);
}
RETURN_IF_NOT_TOKEN(TokenType::RBRACE);
@ -1009,11 +914,7 @@ PResult<IfStmt> ComdelParser::parseIfStatement() {
auto spanner = getSpanner();
IfStmt ifStatement;
IdentifierNode node;
ASSIGN_OR_RETURN_IF_ERR(node, parseIdentifier());
if(node.value != "if") {
return unexpected();
}
RETURN_IF_NOT_TOKEN(TokenType::IF);
RETURN_IF_NOT_TOKEN(TokenType::LPAREN);
@ -1037,17 +938,14 @@ PResult<IfStmt> ComdelParser::parseIfStatement() {
RETURN_IF_NOT_TOKEN(TokenType::LBRACE);
if(check(TokenType::IDENTIFIER)) {
IdentifierNode action;
ASSIGN_OR_RETURN_IF_ERR(action, parseIdentifier());
if(action.value == "error") {
if(check(TokenType::ERROR)) {
ifStatement.action.type = Action::ERROR;
} else if(action.value == "warning") {
} else if(check(TokenType::WARNING)) {
ifStatement.action.type = Action::WARNING;
} else {
return PError(SourceError{action.span, "expected 'error' of 'warning'"});
}
return unexpected();
}
bump();
RETURN_IF_NOT_TOKEN(TokenType::LPAREN);
ASSIGN_OR_RETURN_IF_ERR(ifStatement.action.message, parseString());
@ -1069,6 +967,12 @@ PResult<Value> ComdelParser::parseValue() {
value = Value::ofString(parseString()->value);
} else if(check(TokenType::NUMBER)) {
value = Value::ofInt(parseNumber()->value);
} else if(check(TokenType::TRUE)) {
value = Value::ofBool(true);
} else if(check(TokenType::FALSE)) {
value = Value::ofBool(false);
} else {
return unexpected();
}
return spanner(value);

View File

@ -33,35 +33,3 @@ Token::Token(TokenType type, Span span, std::string text)
, span(std::move(span))
, text(std::move(text))
{}
const std::map<std::string, KeywordType::Type> KeywordType::keywords = {
{"@name", NAME},
{"@info", INFO},
{"@header", HEADER},
{"@directory", DIRECTORY},
{"@library", LIBRARY},
{"@address", ADDRESS},
{"@component", COMPONENT},
{"@messages", MESSAGES},
{"@instanceName", INSTANCE_NAME},
{"@count", COUNT},
{"@display", DISPLAY},
{"@pin", PIN},
{"@tooltip", TOOLTIP},
{"@connection", CONNECTION},
{"@attribute", ATTRIBUTE},
{"@source", SOURCE},
{"@popup", POPUP},
{"@rule", RULE},
{"@title", TITLE},
{"@text", TEXT},
{"@bus", BUS},
{"@wires", WIRES},
{"@enumerated", ENUMERATED},
{"@wire", WIRE},
{"@instance", INSTANCE},
{"@schema", SCHEMA},
{"@position", POSITION},
{"@size", SIZE}
};

View File

@ -56,68 +56,73 @@ enum class TokenType {
COMMENT,
WHITESPACE,
END_OF_FILE
};
IF,
ELSE,
enum class ValueType {
// TYPES
BOOL,
INT,
STRING,
COLOR,
WIRE,
ADDRESS_SPACE,
};
DEFAULT,
class KeywordType {
// BOOLEAN VALUE
TRUE,
FALSE,
public:
enum Type {
// KEYWORDS
NAME,
INFO,
HEADER,
DIRECTORY,
LIBRARY,
ADDRESS,
COMPONENT,
MESSAGES,
INSTANCE_NAME,
COUNT,
DISPLAY,
PIN,
TOOLTIP,
CONNECTION,
ATTRIBUTE,
SOURCE,
POPUP,
RULE,
TITLE,
TEXT,
BUS,
WIRES,
ENUMERATED,
WIRE,
INSTANCE,
SCHEMA,
POSITION,
SIZE,
UNKNOWN
};
KW_NAME,
KW_INFO,
KW_HEADER,
KW_DIRECTORY,
KW_LIBRARY,
KW_ADDRESS,
KW_COMPONENT,
KW_MESSAGES,
KW_INSTANCE_NAME,
KW_COUNT,
KW_DISPLAY,
KW_PIN,
KW_TOOLTIP,
KW_CONNECTION,
KW_ATTRIBUTE,
KW_SOURCE,
KW_POPUP,
KW_RULE,
KW_TITLE,
KW_TEXT,
KW_BUS,
KW_WIRES,
KW_ENUMERATED,
KW_WIRE,
KW_INSTANCE,
KW_SCHEMA,
KW_POSITION,
KW_SIZE,
KW_UNKNOWN,
// TYPES
INT_TYPE,
BOOL_TYPE,
STRING_TYPE,
WIRE_TYPE,
static KeywordType::Type determineType(std::string type) {
if(keywords.count(type) == 0) {
return UNKNOWN;
}
return keywords.at(type);
}
// WIRE TYPES
WIRE_DEFAULT,
WIRE_AND,
WIRE_OR,
R_WIRE,
private:
// PIN_TYPES
PIN_IN,
PIN_OUT,
PIN_IN_OUT,
const static std::map<std::string, KeywordType::Type> keywords;
// COMPONENT TYPES
CT_MEMORY,
CT_PROCESSOR,
// ACTION TYPES
ERROR,
WARNING,
// OTHER
END_OF_FILE
};
struct Token {

View File

@ -3,7 +3,8 @@
enum TokenClass {
BUILT_IN_FUNC = 1,
DATA_TYPE = 2,
KEYWORD_NAME = 4
KEYWORD_NAME = 4,
TOKENIZABLE = 8
};
@ -18,6 +19,8 @@ struct TokenTables {
std::unordered_map<TokenType, TokenInfo> allTokensInfo;
std::unordered_map<std::string, TokenType> keywords;
TokenType tokenize(std::string value, TokenType initial);
void add(TokenType tokenType, const std::string& txt,
unsigned short attribs = 0);
@ -41,9 +44,9 @@ TokenTables::TokenTables() {
add( TokenType::KEYWORD, "keyword" );
// Literals (bool is not here, it has two keywords: false and true)
add( TokenType::NUMBER, "number" );
add( TokenType::STRING, "string" );
add( TokenType::COLOR, "color" );
add( TokenType::NUMBER, "number");
add( TokenType::STRING, "string");
add( TokenType::COLOR, "color");
// Parentheses of all kinds
add( TokenType::LPAREN, "(" );
@ -55,7 +58,7 @@ TokenTables::TokenTables() {
add( TokenType::LT, "<" );
add( TokenType::GT, ">" );
// assignments and resizes
// assignments
add( TokenType::EQUALS, "=" );
// miscellaneous
@ -66,6 +69,69 @@ TokenTables::TokenTables() {
add( TokenType::WHITESPACE, "whitespace" );
add( TokenType::COMMENT, "comment" );
add( TokenType::TRUE, "true", TOKENIZABLE ),
add( TokenType::FALSE, "false", TOKENIZABLE),
add( TokenType::IF, "if", TOKENIZABLE ),
add( TokenType::ELSE, "else", TOKENIZABLE),
add( TokenType::DEFAULT, "default", TOKENIZABLE),
// all keywords
add( TokenType::KW_NAME, "@name", TOKENIZABLE),
add( TokenType::KW_INFO, "@info", TOKENIZABLE),
add( TokenType::KW_HEADER, "@header", TOKENIZABLE),
add( TokenType::KW_DIRECTORY, "@directory", TOKENIZABLE),
add( TokenType::KW_LIBRARY, "@library", TOKENIZABLE),
add( TokenType::KW_ADDRESS, "@address", TOKENIZABLE),
add( TokenType::KW_COMPONENT, "@component", TOKENIZABLE),
add( TokenType::KW_MESSAGES, "@messages", TOKENIZABLE),
add( TokenType::KW_INSTANCE_NAME, "@instanceName", TOKENIZABLE),
add( TokenType::KW_COUNT, "@count", TOKENIZABLE),
add( TokenType::KW_DISPLAY, "@display", TOKENIZABLE),
add( TokenType::KW_PIN, "@pin", TOKENIZABLE),
add( TokenType::KW_TOOLTIP, "@tooltip", TOKENIZABLE),
add( TokenType::KW_CONNECTION, "@connection", TOKENIZABLE),
add( TokenType::KW_ATTRIBUTE, "@attribute", TOKENIZABLE),
add( TokenType::KW_SOURCE, "@source", TOKENIZABLE),
add( TokenType::KW_POPUP, "@popup", TOKENIZABLE),
add( TokenType::KW_RULE, "@rule", TOKENIZABLE),
add( TokenType::KW_TITLE, "@title", TOKENIZABLE),
add( TokenType::KW_TEXT, "@text", TOKENIZABLE),
add( TokenType::KW_BUS, "@bus", TOKENIZABLE),
add( TokenType::KW_WIRES, "@wires", TOKENIZABLE),
add( TokenType::KW_ENUMERATED, "@enumerated", TOKENIZABLE),
add( TokenType::KW_WIRE, "@wire", TOKENIZABLE),
add( TokenType::KW_INSTANCE, "@instance", TOKENIZABLE),
add( TokenType::KW_SCHEMA, "@schema", TOKENIZABLE),
add( TokenType::KW_POSITION, "@position", TOKENIZABLE),
add( TokenType::KW_SIZE, "@size", TOKENIZABLE),
// All types
add( TokenType::INT_TYPE, "int", TOKENIZABLE),
add( TokenType::STRING_TYPE, "string", TOKENIZABLE),
add( TokenType::BOOL_TYPE, "bool", TOKENIZABLE),
add( TokenType::WIRE_TYPE, "wire", TOKENIZABLE),
// Wire types
add( TokenType::WIRE_DEFAULT, "normal_wire", TOKENIZABLE),
add( TokenType::WIRE_AND, "wired_and", TOKENIZABLE),
add( TokenType::WIRE_OR, "wired_or", TOKENIZABLE),
add( TokenType::R_WIRE, "r_wire", TOKENIZABLE),
// Component types
add( TokenType::CT_MEMORY, "memory", TOKENIZABLE),
add( TokenType::CT_PROCESSOR, "processor", TOKENIZABLE),
// Pin type
add( TokenType::PIN_IN, "in", TOKENIZABLE),
add( TokenType::PIN_OUT, "out", TOKENIZABLE),
add( TokenType::PIN_IN_OUT, "inOut", TOKENIZABLE),
// Action types
add( TokenType::ERROR, "error", TOKENIZABLE),
add( TokenType::WARNING, "warning", TOKENIZABLE),
// Built-in functions (they are also keywords)
/*
@ -76,11 +142,23 @@ TokenTables::TokenTables() {
}
const std::string &tokenTypeToString(TokenType tokenType) {
return tokenTables.allTokensInfo[tokenType].text;
}
TokenType TokenTables::tokenize(std::string value, TokenType initial) {
for(auto& [key, param]: allTokensInfo) {
if(param.attributes & TOKENIZABLE && param.text == value) {
return key;
}
}
return initial;
}
TokenType from_token(std::string value, TokenType initial) {
return tokenTables.tokenize(value, initial);
}
bool isBuiltInFunc(TokenType tokenType)
{
return tokenTables.allTokensInfo[tokenType].attributes & BUILT_IN_FUNC;

View File

@ -11,5 +11,6 @@ const std::string& tokenTypeToString(TokenType tokenType);
bool isBuiltInFunc(TokenType tokenType);
bool isDataType(TokenType tokenType);
TokenType from_token(std::string value, TokenType initial);
#endif // TOKENSTYPE_H