home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 40 / IOPROG_40.ISO / SOFT / NETFrameworkSDK.exe / comsdk.cab / samples1.exe / CLisp / Parser.cs < prev    next >
Encoding:
Text File  |  2000-06-23  |  10.2 KB  |  457 lines

  1.  
  2. using System;
  3. using System.Reflection;
  4. using System.Collections;
  5. using Absyn;
  6. using LexToken;
  7.  
  8. class Parser 
  9. {
  10.     Queue tokens;
  11.     public ExpList e;
  12.     bool success;
  13.     Hashtable CurrentVarScope;
  14.     public Hashtable Functions;
  15.     public Hashtable GlobalVars;
  16.     public Hashtable DoVars;
  17.     public int DoVarsCount;
  18.     
  19.     public TypeCheck Tc;
  20.     
  21.     public Parser(Queue t)
  22.     {
  23.     tokens = t;
  24.     success = true;
  25.     Functions = new Hashtable();
  26.     GlobalVars = new Hashtable();
  27.     DoVars = new Hashtable();
  28.     }
  29.  
  30.     public bool Parse()
  31.     {
  32.     //e = null;
  33.     e = MatchStm();
  34.     //    Match(TokenType.EoFSym);
  35.     MatchToken(TokenType.EOFSYM);
  36.     Tc = new TypeCheck(e, Functions);
  37.     bool tsuccess = Tc.Check();
  38.     e = Tc.e;                                       //Exp is modified in TypeCheck
  39.     return success && tsuccess;                     //Return success if both parsing and typechecking succeed.
  40.     }
  41.  
  42.     ExpList MatchStm()
  43.     {
  44.     ExpList ex1 = new ExpList();
  45.     ex1.Head = MatchExp();
  46.     if(((Token)tokens.Peek()).Type != TokenType.EOFSYM){
  47.         ex1.Tail = MatchStm();
  48.     }
  49.     else 
  50.         ex1.Tail = null;
  51.  
  52.     return ex1;
  53.     }
  54.     
  55.     Exp MatchExp()
  56.     {
  57.     AlphaToken at;
  58.     Object o1;
  59.     
  60.     switch(((Token)tokens.Peek()).Type){
  61.     case TokenType.NIL:
  62.         tokens.Dequeue();
  63.         return new StringExp(String.Empty);          //NIL is represented as an empty string
  64.     case TokenType.NUMBER:
  65.         return new IntExp(((NumberToken)tokens.Dequeue()).Value);
  66.     case TokenType.STRING:
  67.         return new StringExp(((StringToken)tokens.Dequeue()).Value);
  68.  
  69.     case TokenType.ALPHA:
  70.         at = (AlphaToken)tokens.Dequeue();
  71.         
  72.         if (DoVars != null && DoVars.Count != 0){
  73.         o1 = DoVars[at.Name];
  74.         if (o1 != null){
  75.             return new DoVarExp(at.Name, (int)o1);
  76.         }
  77.         }
  78.         
  79.         if (CurrentVarScope != null && CurrentVarScope.Count != 0){
  80.         o1 = CurrentVarScope[at.Name];
  81.         if (o1 != null){
  82.             return new VarExp(at.Name, (int)o1);
  83.         }
  84.         }
  85.         o1 = GlobalVars[at.Name];
  86.         
  87.         if(o1 != null){
  88.         return new GlobalVarExp(at.Name);
  89.         }
  90.         Console.WriteLine("Error 6: Undefined Symbol " + at.Name);
  91.         return null;
  92.  
  93.         
  94.     case TokenType.LPAREN:
  95.         MatchToken(TokenType.LPAREN);
  96.         Exp e1, e2, e3;
  97.         Exp [] ea;
  98.         //ListExp el1, el2, el3;
  99.         Token o;
  100.     
  101.  
  102.         switch(((Token)tokens.Peek()).Type){
  103.         case TokenType.PLUS:
  104.         case TokenType.MINUS:
  105.         case TokenType.MUL:
  106.         case TokenType.DIVIDE:
  107.         o = (Token)tokens.Dequeue();
  108.         e1 = MatchExp();
  109.         e2 = MatchExp();
  110.         MatchToken(TokenType.RPAREN);
  111.         return new BinopExp(e1, o ,e2);
  112.  
  113.         case TokenType.LT:
  114.         case TokenType.GT:
  115.         case TokenType.EQ:
  116.         case TokenType.LE:
  117.         case TokenType.GE:
  118.         o = (Token)tokens.Dequeue();
  119.         e1 = MatchExp();
  120.         e2 = MatchExp();
  121.         MatchToken(TokenType.RPAREN);
  122.         return new CompareExp(e1, o ,e2);
  123.         
  124.         case TokenType.CDR:
  125.         tokens.Dequeue();
  126.         e1 = MatchExp();
  127.         MatchToken(TokenType.RPAREN);
  128.         ea = new Exp[1];
  129.  
  130.         ea[0] = e1;
  131.         return new CallExp("LispRuntime", "Cdr", ea, typeof(CList));
  132.         
  133.         case TokenType.CAR:
  134.         tokens.Dequeue();        
  135.         e1 = MatchExp();
  136.         MatchToken(TokenType.RPAREN);
  137.         return new CarExp(e1);
  138.     
  139.         case TokenType.CONS:
  140.         tokens.Dequeue();
  141.         e1 = MatchExp();
  142.         e2 = MatchExp();
  143.         MatchToken(TokenType.RPAREN);
  144.         ea = new Exp[2];
  145.         ea[0] = e1;
  146.         ea[1] = e2;
  147.         return new CallExp("LispRuntime", "Cons", ea, typeof(CList));
  148.         
  149.         case TokenType.SUBST:
  150.         tokens.Dequeue();
  151.         e1 = MatchExp();
  152.         e2 = MatchExp();
  153.         e3 = MatchExp();
  154.         MatchToken(TokenType.RPAREN);
  155.         ea = new Exp[3];
  156.         ea[0] = e1;
  157.         ea[1] = e2;
  158.         ea[2] = e3;
  159.         return new CallExp("LispRuntime", "Subst", ea, typeof(CList));
  160.         
  161.         case TokenType.NULL:
  162.         tokens.Dequeue();
  163.         e1 = MatchExp();
  164.         MatchToken(TokenType.RPAREN);
  165.         ea = new Exp[1];
  166.         ea[0] = e1;
  167.         return new CallExp("LispRuntime", "IsNull", ea, typeof(bool));
  168.         
  169.         case TokenType.ATOM:
  170.         tokens.Dequeue();
  171.         e1 = MatchExp();
  172.         MatchToken(TokenType.RPAREN);
  173.         ea = new Exp[1];
  174.         ea[0] = e1;
  175.         return new CallExp("LispRuntime", "IsAtom", ea, typeof(bool));
  176.         
  177.         case TokenType.IF:
  178.         tokens.Dequeue();
  179.         e1 = MatchExp();
  180.         e2 = MatchExp();
  181.         e3 = MatchExp();
  182.         MatchToken(TokenType.RPAREN);
  183.         return new IfExp(e1, e2, e3);
  184.  
  185.         case TokenType.DO:
  186.         tokens.Dequeue();
  187.         MatchToken(TokenType.LPAREN);
  188.         ExpList el1, el2;
  189.         if (CurrentVarScope == null){
  190.             Console.WriteLine("Error 13: Do must be present in a Function");
  191.             success = false;
  192.             return null;
  193.         }
  194.         
  195.         el1 = MatchDoExpList();
  196.         MatchToken(TokenType.RPAREN);
  197.         //MatchToken(TokenType.LPAREN);
  198.         el2 = MatchDoCondList();
  199.         MatchToken(TokenType.RPAREN);
  200.         return new DoExp(el1, el2);
  201.                 
  202.                 
  203.         case TokenType.SETQ:
  204.         tokens.Dequeue();
  205.         AlphaToken t1 = (AlphaToken)MatchToken(TokenType.ALPHA);
  206.         if(((Token)tokens.Peek()).Type == TokenType.NUMBER){
  207.             e1 = new IntExp(((NumberToken)tokens.Dequeue()).Value);
  208.         }
  209.         else
  210.             e1 = MatchExp();
  211.         GlobalVars.Add(t1.Name, typeof(int));
  212.         MatchToken(TokenType.RPAREN);
  213.         return new GlobalVarDef(t1.Name, e1);
  214.         
  215.         case TokenType.DEFUN:
  216.         ArrayList param = new ArrayList();
  217.         int count = 0;
  218.         if (CurrentVarScope != null){
  219.             Console.WriteLine("Error 12: Nested Functions Not Allowed");
  220.             success = false;
  221.             return null;
  222.         }
  223.         CurrentVarScope = new Hashtable();
  224.         DoVars = new Hashtable();
  225.         DoVarsCount = 0;
  226.         
  227.         tokens.Dequeue();
  228.         AlphaToken t = (AlphaToken)MatchToken(TokenType.ALPHA);
  229.         
  230.         MatchToken(TokenType.LPAREN);
  231.         
  232.         while(((Token)tokens.Peek()).Type == TokenType.ALPHA){
  233.             param.Add(((AlphaToken)tokens.Dequeue()).Name);
  234.             CurrentVarScope.Add(param[count], count++);
  235.         }
  236.         MatchToken(TokenType.RPAREN);
  237.         //CurrentVarScope = param;
  238.         Functions.Add(t.Name, count);
  239.         
  240.         e1 = MatchExp();
  241.         CurrentVarScope = null;
  242.         MatchToken(TokenType.RPAREN);
  243.         return new FunctionDef(t.Name, param, e1);
  244.         
  245.         case TokenType.ALPHA:
  246.         at = (AlphaToken)tokens.Dequeue();
  247.         int iparams;
  248.         
  249.         if( Functions == null || Functions.Count == 0){
  250.             Console.WriteLine("Error 6: Undefined Symbol " + at.Name);
  251.             return null;
  252.         }
  253.         else {
  254.         
  255.             o1 = Functions[at.Name];
  256.             if (o1 == null){
  257.             Console.WriteLine("Error 6: Undefined Symbol " + at.Name);
  258.             return null;
  259.             }
  260.             else {
  261.             iparams = (int)o1;
  262.             }
  263.         }
  264.         Exp [] eparams = new Exp[iparams];
  265.         
  266.         for (int i = 0; i < iparams; i++){
  267.             eparams[i] = MatchExp();
  268.         }
  269.  
  270.         MatchToken(TokenType.RPAREN);
  271.         return new CallExp(null, at.Name, eparams);
  272.         
  273.         default:
  274.         o = null;
  275.         Console.WriteLine("Error 1");
  276.         success = false;
  277.         return null;
  278.         }
  279.     default:
  280.         Console.WriteLine("Error 7: Unexpected Token");
  281.         tokens.Dequeue();
  282.         success = false;
  283.         return null;
  284.         
  285.     }
  286.     
  287.     }
  288.  
  289.     ExpList MatchDoExpList()
  290.     {
  291.     ExpList el1 = new ExpList();
  292.  
  293.     //MatchToken(TokenType.LPAREN);
  294.  
  295.     el1.Head = MatchDoVar();
  296.     if(((Token)tokens.Peek()).Type != TokenType.RPAREN){
  297.         el1.Tail = MatchDoExpList();
  298.     }
  299.     else{
  300.         el1.Tail = null;
  301.     }
  302.  
  303.     //MatchToken(TokenType.RPAREN);
  304.     
  305.     return el1;
  306.     }
  307.  
  308.     Exp MatchDoVar()
  309.     {
  310.     AlphaToken at;
  311.     Exp e1, e2;
  312.     MatchToken(TokenType.LPAREN);
  313.     
  314.     switch(((Token)tokens.Peek()).Type){
  315.     case TokenType.ALPHA:
  316.         at = (AlphaToken)tokens.Dequeue();
  317.         DoVars.Add(at.Name, DoVarsCount);
  318.         int pos = DoVarsCount;
  319.         DoVarsCount++;
  320.         e1 = MatchExp();
  321.         e2 = MatchExp();
  322.         MatchToken(TokenType.RPAREN);
  323.         return new DoVarDef(at.Name, e1, e2, pos);
  324.  
  325.     default:
  326.         Console.WriteLine("Error 10: Expected Variable");
  327.         success = false;
  328.         return null;
  329.     }
  330.     }
  331.     
  332.       
  333.  
  334.     ExpList MatchDoCondList()
  335.     {
  336.     ExpList el1 = new ExpList();
  337.     
  338.     //MatchToken(TokenType.LPAREN);
  339.     
  340.     el1.Head = MatchDoCond();
  341.     if(((Token)tokens.Peek()).Type != TokenType.RPAREN){
  342.         el1.Tail = MatchDoCondList();
  343.     }
  344.     else {
  345.         el1.Tail = null;
  346.     }
  347.     
  348.     //MatchToken(TokenType.RPAREN);
  349.     
  350.     return el1;
  351.     
  352.     }
  353.     
  354.     Exp MatchDoCond()
  355.     {
  356.     Exp e1, e2;
  357.     MatchToken(TokenType.LPAREN);
  358.     e1 = MatchExp();
  359.     e2 = MatchExp();
  360.     MatchToken(TokenType.RPAREN);
  361.     return new DoCondExp(e1, e2);
  362.     }
  363.     
  364.     
  365.  
  366.     /*
  367.     Exp MatchNumericExp()
  368.     {
  369.     switch(((Token)tokens.Peek()).Type){
  370.     case TokenType.NUMBER:
  371.         return new IntExp(((NumberToken)tokens.Dequeue()).Value);
  372.     case TokenType.LPAREN:
  373.         return (NumericExp)MatchExp();
  374.  
  375.  
  376.         default:
  377.         Console.WriteLine("Error 3: Unexpected TOken" + tokens.Peek().ToString());
  378.         success = false;
  379.         return null;
  380.     }
  381.     
  382.     }
  383.     
  384.     Exp MatchListExp()
  385.     {
  386.     switch(((Token)tokens.Peek()).Type){
  387.     case TokenType.NIL:
  388.         MatchToken(TokenType.NIL);
  389.         return new StringExp(String.Empty);
  390.     case TokenType.STRING:
  391.         return new StringExp(((StringToken)tokens.Dequeue()).Value);
  392.     case TokenType.LPAREN:
  393.         return MatchExp();
  394.         default:
  395.         Console.WriteLine("Error 5: Unexpected TOken" + tokens.Peek().ToString());
  396.         success = false;
  397.         return null;
  398.     }
  399.     }
  400.     
  401.         
  402.     
  403.     ListExp MatchListLiteral()
  404.     {
  405.     MatchToken(TokenType.QUOTE);
  406.     switch(((Token)tokens.Peek()).Type){
  407.     case TokenType.ALPHA:
  408.         List al = new List();
  409.         al.Add(((AlphaToken)tokens.Dequeue()).Name);
  410.         return new ListExp(null);
  411.     case TokenType.LPAREN:
  412.         return MatchMultipleList();
  413.     default:
  414.         Console.WriteLine("Error 4: Unexpected Token: " + tokens.Peek().ToString() );
  415.         success = false;
  416.         return null;
  417.     }
  418.     
  419.     }
  420.     */
  421.     /*    
  422.     StringExp MatchMultipleList()
  423.     {
  424.     MatchToken(TokenType.LPAREN);
  425.     String str = "(";
  426.         while(((Token)tokens.Peek()).Type == TokenType.ALPHA){
  427.         al.Add(((AlphaToken)tokens.Dequeue()).Name);
  428.     }
  429.     MatchToken(TokenType.RPAREN);
  430.     return new ListExp(null);
  431.     }
  432.     */
  433.     
  434.     Token MatchToken(TokenType expectedtokentype)
  435.     {
  436.     if(tokens.Count == 0){
  437.         Console.WriteLine("Error 6: UnExpected End of Program");
  438.         return null;
  439.     }
  440.     
  441.     Token t = (Token)tokens.Dequeue();
  442.     if (expectedtokentype != t.Type){
  443.         Console.WriteLine("Error 2: Unexpected Token:" + t.Type.ToString()  + ", expected:" + expectedtokentype.ToString());
  444.         success = false;
  445.     }
  446.     //Console.WriteLine(t);
  447.     return t;
  448.     }
  449.     
  450.     
  451. }
  452.  
  453.  
  454.  
  455.  
  456.  
  457.