Operator precedence I think

This commit is contained in:
2025-12-24 22:01:16 +11:00
parent 7ff306b9e8
commit aa5ef0e664
2 changed files with 104 additions and 10 deletions

View File

@@ -743,6 +743,94 @@ namespace Solstice {
return SolNodeType::Identifier; return SolNodeType::Identifier;
} }
int Parser::getPrecedence(std::string token) {
if (token == "*" || token == "/") return 2;
if (token == "+" || token == "-") return 1;
return 0;
}
SolNode Parser::parsePrimary() {
auto tokenopt = consume();
if (!tokenopt) {
std::cout << "Unexpected end of input\n";
exit(1);
}
std::string token = tokenopt.value();
SolNodeType type = getNodeType(token);
if (type == SolNodeType::Value) {
SolNode node(SolNodeType::Value);
switch (getDataType(token)) {
case SolDataType::Int: node.setValue((int64_t) std::stoll(token)); break;
case SolDataType::Double: node.setValue(std::stod(token)); break;
case SolDataType::String: node.setValue(token.substr(1, token.size() - 2)); break;
case SolDataType::Char: node.setValue(token[1]); break;
case SolDataType::Bool: node.setValue(token == "true"); break;
default: break;
}
return node;
}
if (type == SolNodeType::Identifier) {
SolNode idNode(SolNodeType::Identifier);
idNode.outputId = token;
if (peek().value_or("") == "(") {
consume(); // (
SolNode fnCallNode(SolNodeType::FunctionCall);
fnCallNode.addNode(idNode);
std::vector<std::string> tokens;
size_t brackets = 1;
while (auto t = consume()) {
if (t.value() == "(") brackets++;
if (t.value() == ")") brackets--;
if (brackets == 0) break;
tokens.push_back(t.value());
}
auto args = Parser(tokens).parse();
for(auto& child : args.children) fnCallNode.addNode(child);
return fnCallNode;
}
return idNode;
}
if (type == SolNodeType::BracketStart) {
std::vector<std::string> tokens;
size_t brackets = 1;
while (auto t = consume()) {
if (t.value() == "(") brackets++;
if (t.value() == ")") brackets--;
if (brackets == 0) break;
tokens.push_back(t.value());
}
auto inner = Parser(tokens).parse();
if (inner.children.size() > 0) return inner.children[0];
return SolNode(SolNodeType::None);
}
std::cout << "Unexpected token in expression: " << token << "\n";
exit(1);
}
SolNode Parser::parseExpression(int minPrec) {
SolNode lhs = parsePrimary();
while(true) {
auto opOpt = peek();
if (!opOpt) break;
std::string op = opOpt.value();
int prec = getPrecedence(op);
if (prec < minPrec) break;
consume();
SolNode rhs = parseExpression(prec + 1);
SolNode newNode(getNodeType(op));
newNode.addNode(lhs);
newNode.addNode(rhs);
lhs = newNode;
}
return lhs;
}
SolNode Parser::parse() { SolNode Parser::parse() {
current = 0; current = 0;
size = tokensToParse.size(); size = tokensToParse.size();
@@ -790,17 +878,19 @@ namespace Solstice {
case SolNodeType::Multiply: case SolNodeType::Multiply:
case SolNodeType::Divide: case SolNodeType::Divide:
{ {
SolNode addNode(getNodeType(token)); SolNode opNode(getNodeType(token));
addNode.addNode(rootNode.children.back()); if (rootNode.children.empty()) {
rootNode.children.pop_back(); std::cout << "Expected operand before operator\n";
auto tokenopt = consume();
if (tokenopt) {
addNode.addNode(parseOneToken(tokenopt));
} else {
std::cout << "FEED ME MORE TOKENS\n";
exit(1); exit(1);
} }
rootNode.addNode(addNode); opNode.addNode(rootNode.children.back());
rootNode.children.pop_back();
// Parse RHS with higher precedence
SolNode rhs = parseExpression(getPrecedence(token) + 1);
opNode.addNode(rhs);
rootNode.addNode(opNode);
break; break;
} }
case SolNodeType::Equal: case SolNodeType::Equal:

View File

@@ -109,7 +109,7 @@ namespace Solstice {
size_t current; size_t current;
size_t size; size_t size;
std::optional<std::string> peek(int ahead = 1); std::optional<std::string> peek(int ahead = 0);
std::optional<std::string> consume(); std::optional<std::string> consume();
bool isInt(std::string in); bool isInt(std::string in);
bool isDouble(std::string in); bool isDouble(std::string in);
@@ -118,6 +118,10 @@ namespace Solstice {
bool isBool(std::string in); bool isBool(std::string in);
SolDataType getDataType(std::string in); SolDataType getDataType(std::string in);
SolNodeType getNodeType(std::string in); SolNodeType getNodeType(std::string in);
SolNode parsePrimary();
SolNode parseExpression(int minPrec);
int getPrecedence(std::string token);
public: public:
Parser(std::vector<std::string> in); Parser(std::vector<std::string> in);