FusionCalculator/src/Parser.fu

66 lines
2.1 KiB
Plaintext

class Parser
{
List<Token()> TokenStorage;
Stack<Token>() RPNStack;
IExpression# RootNode;
TokenLinkedList() TokensInRPN;
internal IExpression# Parse!(){
SortTokensInRPN();
BuildTreeFromRPN();
return RootNode;
}
// Implementation of https://en.wikipedia.org/wiki/Shunting_yard_algorithm
void SortTokensInRPN!(){
for(int i = 0; i < TokenStorage.Count; i++){
Token tok = TokenStorage[i];
int type = tok.GetType();
switch(type){
case Token.Type_Number:
TokensInRPN.AddToEnd(tok);
break;
case Token.Type_OperatorPow:
case Token.Type_OperatorMul:
case Token.Type_OperatorDiv:
case Token.Type_OperatorMod:
case Token.Type_OperatorAdd:
case Token.Type_OperatorSub:
while(RPNStack.Count != 0 && RPNStack.Peek().GetType() >= type){
Token op2 = RPNStack.Pop();
TokensInRPN.AddToEnd(op2);
}
RPNStack.Push(tok);
break;
case Token.Type_BracketOpen:
RPNStack.Push(tok);
break;
case Token.Type_BracketClose:
while(RPNStack.Count != 0){
Token op2 = RPNStack.Pop();
TokensInRPN.AddToEnd(op2);
}
break;
case Token.Type_Literal:
// not implemented
assert false;
default:
// unexpected token type
assert false;
}
}
// add remaining operators
while(RPNStack.Count != 0){
Token op2 = RPNStack.Pop();
TokensInRPN.AddToEnd(op2);
}
}
void BuildTreeFromRPN!(){
RootNode = new NumericExpression { N = 0 };
string() graphviz = TokensInRPN.ToGraphVizCode();
Console.WriteLine(graphviz);
}
}