really implemented negative numbers

This commit is contained in:
Timerix22 2023-12-22 23:10:48 +06:00
parent 713784e783
commit 726f4f2425
2 changed files with 7 additions and 14 deletions

View File

@ -37,7 +37,7 @@ class Lexer {
internal List<Token()> Lex!(string exprStr){ internal List<Token()> Lex!(string exprStr){
ExprStr = exprStr; ExprStr = exprStr;
while (i < ExprStr.Length) { for(i=0; i < ExprStr.Length; i++) {
switch (ExprStr[i]) { switch (ExprStr[i]) {
// end token, add new predifined token and move next // end token, add new predifined token and move next
case '(': AddStaticToken(TokBracketOpen); break; case '(': AddStaticToken(TokBracketOpen); break;
@ -47,21 +47,22 @@ class Lexer {
case '%': AddStaticToken(TokMod); break; case '%': AddStaticToken(TokMod); break;
case '/': AddStaticToken(TokDiv); break; case '/': AddStaticToken(TokDiv); break;
case '+': AddStaticToken(TokAdd); break; case '+': AddStaticToken(TokAdd); break;
case '-': AddStaticToken(TokSub); break; case '-':
if(i != 0 && ExprStr[i-1] != '(')
AddStaticToken(TokSub);
// else '-' is a part of numeric expression
break;
// try end token and skip current char // try end token and skip current char
case ' ': case '\t': case '\n': case '\r': case ' ': case '\t': case '\n': case '\r':
TryEndToken(); TryEndToken();
i++;
break; break;
// move next // move next
case '0': case '1': case '2': case '3': case '4': case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9': case '5': case '6': case '7': case '8': case '9':
i++;
break; break;
// set type from Numeric to Literal // set type from Numeric to Literal
default: default:
tokType = Token.Type_Literal; tokType = Token.Type_Literal;
i++;
break; break;
} }
} }
@ -86,6 +87,6 @@ class Lexer {
TokenStorage.Add(); TokenStorage.Add();
TokenStorage[TokenStorage.Count-1] = tok; TokenStorage[TokenStorage.Count-1] = tok;
tokType = Token.Type_Number; tokType = Token.Type_Number;
tokBegin = ++i; tokBegin = i+1;
} }
} }

View File

@ -2,11 +2,9 @@ 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(); // NaN RootExpression = new NumericExpression(); // NaN
TokZero = Token.Create("0", 0, 1, Token.Type_Number);
} }
internal IExpression# Parse!(List<Token()> tokens){ internal IExpression# Parse!(List<Token()> tokens){
@ -26,8 +24,6 @@ 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];
@ -43,8 +39,6 @@ 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().GetTokType() >= type){ while(RPNStack.Count != 0 && RPNStack.Peek().GetTokType() >= type){
Token op2 = RPNStack.Pop(); Token op2 = RPNStack.Pop();
TokensInRPN.AddToEnd(op2); TokensInRPN.AddToEnd(op2);
@ -69,8 +63,6 @@ class Parser {
ThrowError($"unexpected token type '{type}'"); ThrowError($"unexpected token type '{type}'");
break; break;
} }
prevTokType = type;
} }
// add remaining operators // add remaining operators