this repo has no description
at master 26 kB view raw
1using System; 2using System.Collections.Generic; 3using System.Dynamic; 4using System.Linq; 5using System.Reflection; 6using System.Text; 7using System.Threading.Tasks; 8 9namespace Astrid; 10 11public enum Types 12{ 13 String, 14 Int, 15 Float, 16 Bool, 17 ArrayString, 18 ArrayInt, 19 ArrayFloat, 20 ArrayBool 21} 22 23public class AST { } 24 25public class ASTVariableDefine : AST 26{ 27 public string label; 28 public Types type; 29 public ASTExpression value; 30 31 public ASTVariableDefine(string label, Types type, ASTExpression value) 32 { 33 this.label = label; 34 this.type = type; 35 this.value = value; 36 } 37} 38 39public class ASTVariableReassign : AST 40{ 41 public string label; 42 public ASTExpression value; 43 public AssignOp asop; 44 45 public ASTVariableReassign(string label, ASTExpression value, AssignOp asop) 46 { 47 this.label = label; 48 this.value = value; 49 this.asop = asop; 50 } 51} 52 53public class ASTFunctionDefine : AST 54{ 55 public string label; 56 public List<(string, Types)> parameters; 57 public Types? returnType; 58 public List<AST> block; 59 60 public ASTFunctionDefine(string label, List<(string, Types)> parameters, Types? returnType, List<AST> block) 61 { 62 this.label = label; 63 this.parameters = parameters; 64 this.returnType = returnType; 65 this.block = block; 66 } 67} 68 69public class ASTFunctionCall : AST 70{ 71 public string label; 72 public Dictionary<string, ASTExpression> value; 73 74 public ASTFunctionCall(string label, Dictionary<string, ASTExpression> value) 75 { 76 this.label = label; 77 this.value = value; 78 } 79} 80 81public class ASTExpression : AST 82{ 83 public List<object> expression; 84 85 public ASTExpression(List<object> expression) 86 { 87 this.expression = expression; 88 } 89} 90 91public class ASTConditional : AST 92{ 93 public ASTExpression condition; 94 public List<AST> block; 95 96 public ASTConditional(ASTExpression condition, List<AST> block) 97 { 98 this.condition = condition; 99 this.block = block; 100 101 } 102} 103 104public class ASTReturn : AST 105{ 106 public ASTExpression expression; 107 108 public ASTReturn(ASTExpression expression) 109 { 110 this.expression = expression; 111 } 112} 113 114public class ASTWhile : AST 115{ 116 public ASTExpression condition; 117 public List<AST> block; 118 119 public ASTWhile(ASTExpression condition, List<AST> block) 120 { 121 this.condition = condition; 122 this.block = block; 123 124 } 125} 126 127public class ASTMatch : AST 128{ 129 public ASTExpression expr; 130 public Dictionary<ASTExpression, List<AST>> matches; 131 132 public ASTMatch(ASTExpression expr, Dictionary<ASTExpression, List<AST>> matches) 133 { 134 this.expr = expr; 135 this.matches = matches; 136 } 137} 138 139public enum AssignOp 140{ 141 Assign, 142 Plus, 143 Minus, 144 Divide, 145 Multiply, 146 Power, 147 Modulo 148} 149 150public static class Parser 151{ 152 public static (Token[], List<AST>) ParseBlock(Token[] tokens_) 153 { 154 List<Token> tokens = tokens_.ToList(); 155 List<AST> ast = new(); 156 157 while(tokens.Count > 0) 158 { 159 var token = tokens[0]; 160 161 // Tokenizer.Print(token); 162 163 if(token.GetType() == typeof(TokenEOL)) 164 { 165 tokens = tokens.Skip(1).ToList(); 166 } else if(token.GetType() == typeof(TokenBlockEnd)) 167 { 168 tokens = tokens.Skip(1).ToList(); 169 return (tokens.ToArray(), ast); 170 } else if(token.GetType() == typeof(TokenIdentifier)) 171 { 172 var identifierLabel = token.value; 173 tokens = tokens.Skip(1).ToList(); 174 token = tokens[0]; 175 176 if(token.GetType() == typeof(TokenDoubleColon)) 177 { 178 tokens = tokens.Skip(1).ToList(); 179 var (newtokens, newast) = ParseFunctionDefine(tokens.ToArray(), identifierLabel); 180 tokens = newtokens.ToList(); 181 ast.Add(newast); 182 } else if(token.GetType() == typeof(TokenParenStart)) 183 { 184 tokens = tokens.Skip(1).ToList(); 185 var (newtokens, newast) = ParseFunctionCall(tokens.ToArray(), identifierLabel); 186 tokens = newtokens.ToList(); 187 ast.Add(newast); 188 } else if(token.GetType() == typeof(TokenColon)) 189 { 190 tokens = tokens.Skip(1).ToList(); 191 var (newtokens, newast) = ParseVariableDefine(tokens.ToArray(), identifierLabel); 192 tokens = newtokens.ToList(); 193 ast.Add(newast); 194 } else if(new [] {typeof(TokenAssign), typeof(TokenAssignDivide), typeof(TokenAssignMinus), typeof(TokenAssignMultiply), typeof(TokenAssignPlus), typeof(TokenAssignPower), typeof(TokenAssignModulo)}.Contains(token.GetType())) 195 { 196 tokens = tokens.Skip(1).ToList(); 197 var (newtokens, newast) = ParseVariableReassign(tokens.ToArray(), identifierLabel, token); 198 tokens = newtokens.ToList(); 199 ast.Add(newast); 200 } else 201 { 202 Error.Throw("Unexpected token after identifier", token); 203 } 204 } else if(token.GetType() == typeof(TokenKeyword)) 205 { 206 if(token.value == "return") 207 { 208 tokens = tokens.Skip(1).ToList(); 209 var (newtokens, newast) = ParseReturn(tokens.ToArray()); 210 tokens = newtokens.ToList(); 211 ast.Add(newast); 212 } else if(token.value == "if") 213 { 214 tokens = tokens.Skip(1).ToList(); 215 var (newtokens, newast) = ParseConditional(tokens.ToArray()); 216 tokens = newtokens.ToList(); 217 ast.Add(newast); 218 } else if(token.value == "while") 219 { 220 tokens = tokens.Skip(1).ToList(); 221 var (newtokens, newast) = ParseWhile(tokens.ToArray()); 222 tokens = newtokens.ToList(); 223 ast.Add(newast); 224 } else if(token.value == "match") 225 { 226 tokens = tokens.Skip(1).ToList(); 227 var (newtokens, newast) = ParseMatch(tokens.ToArray()); 228 tokens = newtokens.ToList(); 229 ast.Add(newast); 230 } else 231 { 232 Error.Throw("Unimplemented keyword", token); 233 } 234 } else 235 { 236 Error.Throw("Unexpected token", token); 237 } 238 } 239 240 return (tokens.ToArray(), ast); 241 } 242 243 public static Types GetTypeFromToken(Token t, bool array=false) 244 { 245 if(!array) 246 { 247 switch(t.value) 248 { 249 case "int": return Types.Int; 250 case "float": return Types.Float; 251 case "string": return Types.String; 252 case "bool": return Types.Bool; 253 default: Error.Throw($"Invalid type", t); return Types.Int; 254 } 255 } else 256 { 257 switch(t.value) 258 { 259 case "int": return Types.ArrayInt; 260 case "float": return Types.ArrayFloat; 261 case "string": return Types.ArrayString; 262 case "bool": return Types.ArrayBool; 263 default: Error.Throw($"Invalid type", t); return Types.Int; 264 } 265 } 266 } 267 268 public static Types GetTypeFromValue(Token t) 269 { 270 if(t.GetType() == typeof(TokenInt)) 271 { 272 return Types.Int; 273 } else if(t.GetType() == typeof(TokenFloat)) 274 { 275 return Types.Float; 276 } else if(t.GetType() == typeof(TokenString)) 277 { 278 return Types.String; 279 } 280 Error.Throw($"Invalid type", t); 281 return Types.Int; 282 } 283 284 public static (Token[], AST) ParseConditional(Token[] tokens_) 285 { 286 List<Token> tokens = tokens_.ToList(); 287 AST ast = new(); 288 289 var (newtokens, expr) = ParseExpression(tokens.ToArray()); 290 tokens = newtokens.ToList(); 291 292 (newtokens, var astblock) = ParseBlock(tokens.ToArray()); 293 tokens = newtokens.ToList(); 294 295 return (tokens.ToArray(), new ASTConditional(expr, astblock)); 296 } 297 298 public static (Token[], AST) ParseWhile(Token[] tokens_) 299 { 300 List<Token> tokens = tokens_.ToList(); 301 AST ast = new(); 302 303 var (newtokens, expr) = ParseExpression(tokens.ToArray()); 304 tokens = newtokens.ToList(); 305 306 (newtokens, var astblock) = ParseBlock(tokens.ToArray()); 307 tokens = newtokens.ToList(); 308 309 return (tokens.ToArray(), new ASTWhile(expr, astblock)); 310 } 311 312 public static (Token[], AST) ParseMatch(Token[] tokens_) 313 { 314 List<Token> tokens = tokens_.ToList(); 315 AST ast = new(); 316 317 var (newtokens, expr) = ParseExpression(tokens.ToArray()); 318 tokens = newtokens.ToList(); 319 320 var token = tokens[0]; 321 322 Dictionary<ASTExpression, List<AST>> matches = new(); 323 324 bool matchesDone = false; 325 326 while(tokens.Count > 0 && !matchesDone) 327 { 328 token = tokens[0]; 329 // Tokenizer.Print(token); 330 331 (newtokens, var matchexpr) = ParseExpression(tokens.ToArray()); 332 tokens = newtokens.ToList(); 333 token = tokens[0]; 334 335 if(token.GetType() == typeof(TokenBlockStart)) 336 { 337 tokens = tokens.Skip(1).ToList(); 338 token = tokens[0]; 339 } else 340 { 341 Error.Throw("Expected block start after match expression", token); 342 } 343 344 (newtokens, var block) = ParseBlock(tokens.ToArray()); 345 tokens = newtokens.ToList(); 346 347 token = tokens[0]; 348 349 // tokens = tokens.Skip(1).ToList(); 350 351 matches.Add(matchexpr, block); 352 353 if(token.GetType() == typeof(TokenBlockEnd)) 354 { 355 return (tokens.ToArray(), new ASTMatch(expr, matches)); 356 } 357 } 358 359 return (tokens.ToArray(), new ASTMatch(expr, matches)); 360 } 361 362 public static (Token[], AST) ParseFunctionDefine(Token[] tokens_, string label) 363 { 364 List<Token> tokens = tokens_.ToList(); 365 AST ast = new(); 366 367 var token = tokens[0]; 368 369 if(token.GetType() == typeof(TokenParenStart)) 370 { 371 tokens = tokens.Skip(1).ToList(); 372 token = tokens[0]; 373 } else 374 { 375 Error.Throw("Expected left parenthesis '(' after double colon '::'", token); 376 } 377 378 List<(string, Types)> parameters = new(); 379 380 bool parametersDone = false; 381 while(tokens.Count > 0 || !parametersDone) 382 { 383 token = tokens[0]; 384 385 if(token.GetType() == typeof(TokenParenEnd)) 386 { 387 tokens = tokens.Skip(1).ToList(); 388 token = tokens[0]; 389 parametersDone = true; 390 break; 391 } 392 393 var parameterLabel = ""; 394 if(token.GetType() == typeof(TokenIdentifier)) 395 { 396 parameterLabel = token.value; 397 tokens = tokens.Skip(1).ToList(); 398 token = tokens[0]; 399 } else { 400 Error.Throw("Expected identifier as paramter label", token); 401 } 402 403 if(token.GetType() == typeof(TokenColon)) 404 { 405 tokens = tokens.Skip(1).ToList(); 406 token = tokens[0]; 407 } else 408 { 409 Error.Throw("Expected colon after parameter label", token); 410 } 411 412 Token type = default(Token)!; 413 if(token.GetType() == typeof(TokenIdentifier)) 414 { 415 type = token; 416 tokens = tokens.Skip(1).ToList(); 417 token = tokens[0]; 418 } else { 419 Error.Throw("Expected type", token); 420 } 421 422 // Console.WriteLine("i"); 423 parameters.Add((parameterLabel, GetTypeFromToken(type))); 424 425 if(token.GetType() == typeof(TokenParenEnd)) 426 { 427 parametersDone = true; 428 tokens = tokens.Skip(1).ToList(); 429 token = tokens[0]; 430 431 break; 432 } 433 434 if(token.GetType() == typeof(TokenComma)) 435 { 436 tokens = tokens.Skip(1).ToList(); 437 token = tokens[0]; 438 } else 439 { 440 Error.Throw("Expected comma after parameter label", token); 441 } 442 } 443 444 Types? returnType = null; 445 if(token.GetType() == typeof(TokenIdentifier)) 446 { 447 if(token.value == "void") 448 { 449 returnType = null; 450 } else 451 { 452 returnType = GetTypeFromToken(token); 453 } 454 // Console.WriteLine("2"); 455 tokens = tokens.Skip(1).ToList(); 456 token = tokens[0]; 457 } else { 458 Error.Throw("Expected return type", token); 459 } 460 461 List<AST> block = new(); 462 if(token.GetType() == typeof(TokenBlockStart)) 463 { 464 tokens = tokens.Skip(1).ToList(); 465 token = tokens[0]; 466 467 var (newtokens, newast) = ParseBlock(tokens.ToArray()); 468 block = newast; 469 tokens = newtokens.ToList(); 470 } else { 471 Error.Throw("Expected block start", token); 472 } 473 474 ast = new ASTFunctionDefine(label, parameters, returnType, block); 475 476 return (tokens.ToArray(), ast); 477 } 478 479 public static (Token[], AST) ParseFunctionCall(Token[] tokens_, string function) 480 { 481 List<Token> tokens = tokens_.ToList(); 482 AST ast = new(); 483 484 Dictionary<string, ASTExpression> parameters = new(); 485 486 bool parametersDone = false; 487 while(tokens.Count > 0 || !parametersDone) 488 { 489 var token = tokens[0]; 490 491 if(token.GetType() == typeof(TokenParenEnd)) 492 { 493 tokens = tokens.Skip(1).ToList(); 494 token = tokens[0]; 495 parametersDone = true; 496 break; 497 } 498 499 var parameterLabel = ""; 500 if(token.GetType() == typeof(TokenIdentifier)) 501 { 502 parameterLabel = token.value; 503 tokens = tokens.Skip(1).ToList(); 504 token = tokens[0]; 505 } else { 506 Error.Throw("Expected identifier as paramter label", token); 507 } 508 509 if(token.GetType() == typeof(TokenColon)) 510 { 511 tokens = tokens.Skip(1).ToList(); 512 token = tokens[0]; 513 } else 514 { 515 Error.Throw("Expected colon after parameter label", token); 516 } 517 518 var (newtokens, newast) = ParseExpression(tokens.ToArray()); 519 // Console.WriteLine(tokens[tokens.Count - newtokens.Length - 1]); 520 521 var newtok = newtokens.ToList(); 522 newtok = newtok.Prepend(tokens[tokens.Count - newtokens.Length - 1]).ToList(); 523 tokens = newtok.ToArray().ToList(); 524 token = tokens[0]; 525 526 parameters.Add(parameterLabel, newast); 527 528 if(token.GetType() == typeof(TokenParenEnd) || token.GetType() == typeof(TokenEOL)) 529 { 530 tokens = tokens.Skip(1).ToList(); 531 return (tokens.ToArray(), new ASTFunctionCall(function, parameters)); 532 } else if(token.GetType() == typeof(TokenComma)) 533 { 534 tokens = tokens.Skip(1).ToList(); 535 } 536 } 537 return (tokens.ToArray(), new ASTFunctionCall(function, parameters)); 538 } 539 540 public static (Token[], AST) ParseReturn(Token[] tokens) 541 { 542 var (newtokens, newast) = ParseExpression(tokens); 543 544 return (newtokens, new ASTReturn(newast)); 545 } 546 547 public static (Token[], AST) ParseVariableDefine(Token[] tokens_, string label) 548 { 549 List<Token> tokens = tokens_.ToList(); 550 AST ast = new(); 551 552 var token = tokens[0]; 553 554 Types type = Types.Int; 555 if(token.GetType() == typeof(TokenIdentifier)) 556 { 557 // Console.WriteLine("3"); 558 type = GetTypeFromToken(token); 559 tokens = tokens.Skip(1).ToList(); 560 token = tokens[0]; 561 } else if(token.GetType() == typeof(TokenArrayStart)) 562 { 563 tokens = tokens.Skip(1).ToList(); 564 token = tokens[0]; 565 type = GetTypeFromToken(token, true); 566 tokens = tokens.Skip(1).ToList(); 567 token = tokens[0]; 568 569 if(token.GetType() == typeof(TokenArrayEnd)) 570 { 571 tokens = tokens.Skip(1).ToList(); 572 token = tokens[0]; 573 } else 574 { 575 Error.Throw("Expected array end after array type definition", token); 576 } 577 } else 578 { 579 Error.Throw("Expected type", token); 580 } 581 582 if(token.GetType() == typeof(TokenAssign)) 583 { 584 tokens = tokens.Skip(1).ToList(); 585 token = tokens[0]; 586 } else 587 { 588 Error.Throw("Expected assign '='", token); 589 } 590 591 var (newtokens, expr) = ParseExpression(tokens.ToArray()); 592 593 tokens = newtokens.ToList(); 594 595 return (tokens.ToArray(), new ASTVariableDefine(label, type, expr)); 596 } 597 598 public static (Token[], AST) ParseVariableReassign(Token[] tokens_, string label, Token op) 599 { 600 AssignOp asop = AssignOp.Assign; 601 if(op.GetType() == typeof(TokenAssign)) 602 { 603 asop = AssignOp.Assign; 604 } else if(op.GetType() == typeof(TokenAssignDivide)) 605 { 606 asop = AssignOp.Divide; 607 } else if(op.GetType() == typeof(TokenAssignMinus)) 608 { 609 asop = AssignOp.Minus; 610 } else if(op.GetType() == typeof(TokenAssignMultiply)) 611 { 612 asop = AssignOp.Multiply; 613 } else if(op.GetType() == typeof(TokenAssignPlus)) 614 { 615 asop = AssignOp.Plus; 616 } else if(op.GetType() == typeof(TokenAssignPower)) 617 { 618 asop = AssignOp.Power; 619 } else if(op.GetType() == typeof(TokenAssignModulo)) 620 { 621 asop = AssignOp.Power; 622 } else 623 { 624 Error.Throw("Invalid operator", op); 625 } 626 627 List<Token> tokens = tokens_.ToList(); 628 629 var token = tokens[0]; 630 631 var (newtokens, expr) = ParseExpression(tokens.ToArray()); 632 633 return (newtokens, new ASTVariableReassign(label, expr, asop)); 634 } 635 636 public static Type[] ExprValues = new [] {typeof(TokenInt), typeof(TokenFloat), typeof(TokenString), typeof(TokenIdentifier)}; 637 638 public static Dictionary<Type, (int, bool)> ExprOperatorsEquality = new() 639 { 640 {typeof(TokenEquals), (0, false)}, 641 {typeof(TokenNotEquals), (0, false)}, 642 {typeof(TokenGreater), (1, false)}, 643 {typeof(TokenGreaterEquals), (1, false)}, 644 {typeof(TokenLesser), (1, false)}, 645 {typeof(TokenLesserEquals), (1, false)} 646 }; 647 648 public static Dictionary<Type, (int, bool)> ExprOperatorsAlgebraic = new() 649 { 650 {typeof(TokenPlus), (2, false)}, 651 {typeof(TokenMinus), (2, false)}, 652 {typeof(TokenDivide), (3, false)}, 653 {typeof(TokenMultiply), (3, false)}, 654 {typeof(TokenModulo), (3, false)}, 655 {typeof(TokenPower), (4, true)}, 656 }; 657 658 public static Dictionary<Type, (int, bool)> ExprOperatorsBoolean = new() 659 { 660 {typeof(TokenNot), (4, true)} 661 }; 662 663 public static Dictionary<Type, (int, bool)> ExprOperators = new(); 664 665 public static (Token[], Token) ParseArray(Token[] tokens_) 666 { 667 List<Token> tokens = tokens_.ToList(); 668 669 Types type; 670 while(tokens.Count > 0) 671 { 672 var token = tokens[0]; 673 674 if(token is TokenArrayEnd) 675 { 676 Token list; 677 if(type == null) 678 { 679 list = new TokenArrayInt(0, 0, 0, 0); 680 } 681 682 return (tokens.ToList(), ) 683 } 684 } 685 } 686 687 public static (Token[], ASTExpression) ParseExpression(Token[] tokens_) 688 { 689 List<Token> tokens = tokens_.ToList(); 690 List<AST> ast = new(); 691 692 List<Token> OperatorQueue = new(); 693 List<object> OutputQueue = new(); 694 695 int leftParens = 0; 696 int rightParens = 0; 697 698 List<Token> fixedTokens = new(); 699 700 foreach(var token in tokens) 701 { 702 if(token is not TokenArrayStart) 703 { 704 fixedTokens.Add(token); 705 } else 706 { 707 var (newtokens, list) = ParseArray(tokens.ToArray()); 708 } 709 } 710 711 while(tokens.Count > 0) 712 { 713 var token = tokens[0]; 714 tokens = tokens.Skip(1).ToList(); 715 716 if(token.GetType() == typeof(TokenParenStart)) 717 { 718 leftParens ++; 719 } 720 if(token.GetType() == typeof(TokenParenEnd)) 721 { 722 rightParens++; 723 } 724 725 // Console.WriteLine("expr " + Tokenizer.GetTokenAsHuman(token)); 726 727 // Tokenizer.Print(token); 728 729 if( 730 new [] {typeof(TokenEOL), typeof(TokenBlockStart), typeof(TokenComma), typeof(TokenColon)}.Contains(token.GetType()) || 731 ( 732 new [] {typeof(TokenEOL), typeof(TokenBlockStart), typeof(TokenComma)}.Contains(tokens[0].GetType()) && 733 new [] {typeof(TokenParenEnd)}.Contains(token.GetType()) 734 ) || 735 (rightParens > leftParens) 736 ) 737 { 738 while(OperatorQueue.Count > 0) 739 { 740 if(OperatorQueue.Last().GetType() == typeof(TokenParenStart)) 741 Error.Throw("Can't be left parnthesis", OperatorQueue.Last()); 742 743 OutputQueue.Add(OperatorQueue.Last()); 744 OperatorQueue.RemoveAt(OperatorQueue.Count - 1); 745 } 746 747 return (tokens.ToArray(), new ASTExpression(OutputQueue)); 748 } 749 750 if(ExprValues.Contains(token.GetType())) 751 { 752 if(token.GetType() == typeof(TokenIdentifier)) 753 { 754 if(tokens[0].GetType() == typeof(TokenParenStart)) 755 { 756 // Console.WriteLine("Parsing function"); 757 tokens = tokens.Skip(1).ToList(); 758 var (newtokens, newast) = ParseFunctionCall(tokens.ToArray(), token.value); 759 tokens = newtokens.ToList(); 760 OutputQueue.Add(newast); 761 // Console.Write("Parsed fc "); 762 // Tokenizer.Print(tokens[0]); 763 // Console.WriteLine("done parse"); 764 } else { 765 OutputQueue.Add(token); 766 } 767 } else 768 { 769 OutputQueue.Add(token); 770 } 771 772 } else if(ExprOperators.Keys.Contains(token.GetType())) 773 { 774 while( 775 (OperatorQueue.Count > 0 && OperatorQueue.Last().GetType() != typeof(TokenParenStart)) 776 && 777 ( 778 ExprOperators[OperatorQueue.Last().GetType()].Item1 > ExprOperators[token.GetType()].Item1 779 || 780 (ExprOperators[OperatorQueue.Last().GetType()].Item1 == ExprOperators[token.GetType()].Item1 && !ExprOperators[token.GetType()].Item2) 781 ) 782 ) 783 { 784 OutputQueue.Add(OperatorQueue.Last()); 785 OperatorQueue.RemoveAt(OperatorQueue.Count - 1); 786 } 787 788 OperatorQueue.Add(token); 789 } else if(token.GetType() == typeof(TokenParenStart)) 790 { 791 OperatorQueue.Add(token); 792 } else if(token.GetType() == typeof(TokenParenEnd)) 793 { 794 while( 795 OperatorQueue.Last().GetType() != typeof(TokenParenStart) 796 ) { 797 if(OperatorQueue.Count == 0) 798 Error.Throw("Unmatched parnthesis", OperatorQueue.Last()); 799 800 OutputQueue.Add(OperatorQueue.Last()); 801 OperatorQueue.RemoveAt(OperatorQueue.Count - 1); 802 } 803 804 // if(OperatorQueue.Last().GetType() == typeof(TokenParenStart)) 805 // Error.Throw("Expected left parnthesis", OperatorQueue.Last()); 806 807 OperatorQueue.RemoveAt(OperatorQueue.Count - 1); 808 } 809 } 810 811 while(OperatorQueue.Count > 0) 812 { 813 if(OperatorQueue.Last().GetType() == typeof(TokenParenStart)) 814 Error.Throw("Can't be left parnthesis", OperatorQueue.Last()); 815 816 OutputQueue.Add(OperatorQueue.Last()); 817 OperatorQueue.RemoveAt(OperatorQueue.Count - 1); 818 } 819 820 return (tokens.ToArray(), new ASTExpression(OutputQueue)); 821 } 822}