negative numbers parsing
This commit is contained in:
parent
cc6cda554c
commit
5a4b2ce3f6
@ -3,9 +3,11 @@ class Parser
|
|||||||
List<Token()> TokenStorage;
|
List<Token()> TokenStorage;
|
||||||
IExpression# RootExpression;
|
IExpression# RootExpression;
|
||||||
TokenLinkedList() TokensInRPN;
|
TokenLinkedList() TokensInRPN;
|
||||||
|
Token() TokZero;
|
||||||
|
|
||||||
internal Parser(){
|
internal Parser(){
|
||||||
RootExpression = new NumericExpression { N = Math.NaN };
|
RootExpression = new NumericExpression { N = Math.NaN };
|
||||||
|
TokZero = Token.Create("0", 0, 1, Token.Type_Number);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal IExpression# Parse!(){
|
internal IExpression# Parse!(){
|
||||||
@ -22,9 +24,13 @@ class Parser
|
|||||||
// Implementation of https://en.wikipedia.org/wiki/Shunting_yard_algorithm
|
// Implementation of https://en.wikipedia.org/wiki/Shunting_yard_algorithm
|
||||||
void SortTokensInRPN!(){
|
void SortTokensInRPN!(){
|
||||||
Stack<Token>() RPNStack;
|
Stack<Token>() RPNStack;
|
||||||
|
// is needed for negative numbers recognition
|
||||||
|
int prevTokType = Token.Type_BracketOpen;
|
||||||
|
|
||||||
for(int i = 0; i < TokenStorage.Count; i++){
|
for(int i = 0; i < TokenStorage.Count; i++){
|
||||||
Token tok = TokenStorage[i];
|
Token tok = TokenStorage[i];
|
||||||
int type = tok.GetType();
|
int type = tok.GetType();
|
||||||
|
|
||||||
switch(type){
|
switch(type){
|
||||||
case Token.Type_Number:
|
case Token.Type_Number:
|
||||||
TokensInRPN.AddToEnd(tok);
|
TokensInRPN.AddToEnd(tok);
|
||||||
@ -35,6 +41,8 @@ class Parser
|
|||||||
case Token.Type_OperatorMod:
|
case Token.Type_OperatorMod:
|
||||||
case Token.Type_OperatorAdd:
|
case Token.Type_OperatorAdd:
|
||||||
case Token.Type_OperatorSub:
|
case Token.Type_OperatorSub:
|
||||||
|
if(type == Token.Type_OperatorSub && prevTokType == Token.Type_BracketOpen)
|
||||||
|
TokensInRPN.AddToEnd(TokZero);
|
||||||
while(RPNStack.Count != 0 && RPNStack.Peek().GetType() >= type){
|
while(RPNStack.Count != 0 && RPNStack.Peek().GetType() >= type){
|
||||||
Token op2 = RPNStack.Pop();
|
Token op2 = RPNStack.Pop();
|
||||||
TokensInRPN.AddToEnd(op2);
|
TokensInRPN.AddToEnd(op2);
|
||||||
@ -47,9 +55,8 @@ class Parser
|
|||||||
case Token.Type_BracketClose:
|
case Token.Type_BracketClose:
|
||||||
while(RPNStack.Count != 0){
|
while(RPNStack.Count != 0){
|
||||||
Token op2 = RPNStack.Pop();
|
Token op2 = RPNStack.Pop();
|
||||||
if(op2.GetType() == Token.Type_BracketOpen){
|
if(op2.GetType() == Token.Type_BracketOpen)
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
TokensInRPN.AddToEnd(op2);
|
TokensInRPN.AddToEnd(op2);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -60,6 +67,8 @@ class Parser
|
|||||||
ThrowError("unexpected token type");
|
ThrowError("unexpected token type");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prevTokType = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
// add remaining operators
|
// add remaining operators
|
||||||
@ -76,8 +85,9 @@ class Parser
|
|||||||
TokenLinkedListNode? tokenNode = TokensInRPN.GetFirstNode();
|
TokenLinkedListNode? tokenNode = TokensInRPN.GetFirstNode();
|
||||||
while(tokenNode != null){
|
while(tokenNode != null){
|
||||||
Token tok = tokenNode.GetValue();
|
Token tok = tokenNode.GetValue();
|
||||||
|
int type = tok.GetType();
|
||||||
|
|
||||||
switch(tok.GetType()){
|
switch(type){
|
||||||
case Token.Type_Number:
|
case Token.Type_Number:
|
||||||
expressionStack.Push(new NumericExpression { N = StringToDouble(tok.GetStr()) });
|
expressionStack.Push(new NumericExpression { N = StringToDouble(tok.GetStr()) });
|
||||||
break;
|
break;
|
||||||
@ -100,14 +110,16 @@ class Parser
|
|||||||
PushOperatorExpression(expressionStack, tok, new OperatorExpressionSub());
|
PushOperatorExpression(expressionStack, tok, new OperatorExpressionSub());
|
||||||
break;
|
break;
|
||||||
case Token.Type_BracketClose:
|
case Token.Type_BracketClose:
|
||||||
|
ThrowError("unexpected (");
|
||||||
|
break;
|
||||||
case Token.Type_BracketOpen:
|
case Token.Type_BracketOpen:
|
||||||
ThrowError("brackets should be handled at SortTokensInRPN");
|
ThrowError("unexpected )");
|
||||||
break;
|
break;
|
||||||
case Token.Type_Literal:
|
case Token.Type_Literal:
|
||||||
ThrowError("not implemented");
|
ThrowError("not implemented");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ThrowError("unexpected token type");
|
ThrowError($"unexpected token type: {type}");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,7 +151,7 @@ class Parser
|
|||||||
|
|
||||||
void PushOperatorExpression(Stack<IExpression#>! expressionStack, Token tok, OperatorExpression# opExpr) {
|
void PushOperatorExpression(Stack<IExpression#>! expressionStack, Token tok, OperatorExpression# opExpr) {
|
||||||
if(expressionStack.Count < 2){
|
if(expressionStack.Count < 2){
|
||||||
ThrowError("input error: unexpected operator "+tok.GetStr());
|
ThrowError($"unexpected operator: {tok.GetStr()}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
IExpression b = expressionStack.Pop();
|
IExpression b = expressionStack.Pop();
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user