private async Task <Expr> ParseExpr() { while (await mTokenizer.NextToken()) { switch (mTokenizer.Token) { case ETokenType.Number: return(Expr.MakeNumber(mTokenizer.Number)); default: throw new STException(string.Format(Properties.Resources.NoExpectTokenException, mTokenizer.TokenStr), mTokenizer.Line, mTokenizer.Position); } } return(null); }
/// <summary> /// Splitting (“3 - 2 * 6 - 1”) = [3, ‘-’], [2, ‘*’], [6, ‘-’], [1, ‘’] /// </summary> /// <returns></returns> private async Task <LinkedList <Cell> > Split() { var pCells = new LinkedList <Cell>(); Cell pCell = null; var pNegative = false; Expr pExpr; while (await mTokenizer.NextToken()) { if (Symbols.DictOperators.TryGetValue(mTokenizer.Token, out ETypeExpr op)) { if (op == ETypeExpr.Equal) { return(pCells); } if (pCell != null) { if (pNegative) { pCell.Expr = Expr.Negative(pCell.Expr); pNegative = false; } pCell.TypeOp = op; pCell = null; } else { if (!pNegative) { switch (op) { case ETypeExpr.Subtract: pNegative = true; continue; case ETypeExpr.Add: continue; default: throw new STException(string.Format(Properties.Resources.NoExpectTokenException, mTokenizer.TokenStr), mTokenizer.Line, mTokenizer.Position); } } throw new STException(string.Format(Properties.Resources.NoExpectTokenException, mTokenizer.TokenStr), mTokenizer.Line, mTokenizer.Position); } } else { if (Symbols.DictFuncs.TryGetValue(mTokenizer.Token, out ETypeExpr fn)) { if (!await mTokenizer.NextToken()) { throw new STException(string.Format(Properties.Resources.ExpectTokenException, Symbols.OpenParensChar), mTokenizer.Line, mTokenizer.Position); } mTokenizer.Back(); var pExprArg = await ParseExpr(); pExpr = Expr.Function(fn, pExprArg); } else { switch (mTokenizer.Token) { case ETokenType.CloseParens: return(pCells); case ETokenType.OpenParens: pExpr = await ParseExpr(); if (mTokenizer.Token == ETokenType.Equal) { mTokenizer.Back(); } break; case ETokenType.Number: pExpr = Expr.Number(mTokenizer.Number); break; case ETokenType.Identifier: pExpr = Expr.Literal(mTokenizer.Identifier); break; default: throw new STException(string.Format(Properties.Resources.NoExpectTokenException, mTokenizer.TokenStr), mTokenizer.Line, mTokenizer.Position); } } if (pNegative) { pExpr = Expr.Negative(pExpr); pNegative = false; } if (pCell != null) { pCell.TypeOp = ETypeExpr.Multiply; } pCell = new Cell(pExpr); pCells.AddLast(pCell); } } return(pCells); }
//[Test] static async Task TokernizerTest() { var pTexts = new[] { //"20$", //"20", //"20x", //"(20)", //"20x+30y+20x^2", //"(sin (x))^2+(cos (x))^2=1" //"x", //"2x=3", "20a+3b+c=1\nb=20", }; foreach (var pText in pTexts) { try { using (var pReader = new StringReader(pText)) { var pTokenizer = new ST.Tokenizer(pReader, CancellationToken.None, true); Console.WriteLine($"{pText} :"); while (await pTokenizer.NextToken()) { Console.Write($"Token : {pTokenizer.Token} "); switch (pTokenizer.Token) { case ST.ETokenType.Number: Console.WriteLine(pTokenizer.Number); break; case ST.ETokenType.Identifier: Console.WriteLine(pTokenizer.Identifier); break; default: Console.WriteLine(); break; } if (pTokenizer.EOF) { Console.WriteLine("EOF"); } if (pTokenizer.EOL) { Console.WriteLine("EOL"); pTokenizer.ResetEOL = true; } } } } catch (ST.STException ex) { var pLine = string.Empty; using (var pReader = new StringReader(pText)) { for (var i = ex.Line; i > 0; i--) { pLine = pReader.ReadLine(); } } PrintError(ex.Message); PrintError(pLine); PrintError($"{new string(' ', ex.Position - 1)}^"); } catch (Exception ex) { PrintError(ex.Message); } } }