DIRECTORY
  ParseDefs USING [Value, Value2],
  TreesDefs USING [MakeNode];

ParseStmtsImpl: PROGRAM IMPORTS TreesDefs EXPORTS ParseDefs = {
  
  ParseStmts: PUBLIC PROCEDURE [rule: CARDINAL, top: CARDINAL,
  	v: LONG DESCRIPTOR FOR ARRAY OF ParseDefs.Value,
	v2: LONG DESCRIPTOR FOR ARRAY OF ParseDefs.Value2] = {
    temp: ParseDefs.Value;
    temp2: ParseDefs.Value2;
    atemp: LONG POINTER TO LONG STRING ← @temp;
    avtop: LONG POINTER TO LONG STRING ← @v[top];

      SELECT rule FROM
	  		--	DECLARATION VARIABLE LISTS (WITH INITIALIZERS)	--

       60  =>  -- InitDclList  ::=	InitDcltor
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top], right: NIL,
	      string: NIL, nodeType: dclItemList];
	  v2[top].lastInList ← v2[top];
          };
       61  =>  -- InitDclList  ::=	InitDclList  ,  InitDcltor
          {
	  temp2 ← TreesDefs.MakeNode[left: v2[top + 2], right: NIL,
	      string: NIL, nodeType: dclItemList];
	  v2[top].lastInList.right ← temp2;
	  v2[top].lastInList ← temp2;
          };
       62  =>  -- InitDcltor  ::=	Declarator
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top], right: NIL,
	      string: NIL, nodeType: itemHead];
          };
       63  =>  -- InitDcltor  ::=	Declarator  =  e
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top], right: v2[top + 2],
	      string: NIL, nodeType: itemHead];
          };
       64  =>  -- InitDcltor  ::=	Declarator  =  {  InitList  Optcomma  }
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top], right: v2[top + 3],
	      string: NIL, nodeType: itemHead];
          };
       65  =>  -- InitList  ::=		Initializer
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top], right: NIL,
	      string: NIL, nodeType: operation];
	  v2[top].operationType ← eList;
	  v2[top].lastInList ← v2[top];
          };
       66  =>  -- InitList  ::=		InitList  ,  Initializer
          {
	  temp2 ← TreesDefs.MakeNode[left: v2[top + 2], right: NIL,
	      string: NIL, nodeType: operation];
	  v2[top].operationType ← eList;
	  v2[top].lastInList.right ← temp2;
	  v2[top].lastInList ← temp2;
          };
       67  =>  -- Initializer  ::=	e
          NULL;
       68  =>  -- Initializer  ::=	{  InitList  Optcomma  }
          {
	  v2[top] ← TreesDefs.MakeNode[left: NIL, right: v2[top + 1],
	      string: NIL, nodeType: operation];
	  v2[top].operationType ← eList;
          };
	  
	  		--	ENUMERATIONS	--

       69  =>  -- EnumDcl  ::=		EnumHead  {  MOEList  Optcomma  }
          {
	  v2[top].left ← v2[top + 2];
          };
       70  =>  -- EnumDcl  ::=		enum  NAME
          {
	  v2[top] ← TreesDefs.MakeNode[left: NIL, right: NIL,
	      string: v[top + 1], nodeType: attributes];
	  v2[top].enumeration ← TRUE;
	  };
       71  =>  -- EnumHead  ::=		enum
          {
	  v2[top] ← TreesDefs.MakeNode[left: NIL, right: NIL,
	      string: NIL, nodeType: attributes];
	  v2[top].enumeration ← TRUE;
	  };
	  
       72  =>  -- EnumHead  ::=		enum NAME
          {
	  v2[top] ← TreesDefs.MakeNode[left: NIL, right: NIL,
	      string: v[top + 1], nodeType: attributes];
	  v2[top].enumeration ← TRUE;
	  };
       73  =>  -- MOEList  ::=		MOE
          {
	   v2[top] ← TreesDefs.MakeNode[left: v2[top], right: NIL,
	      string: NIL, nodeType: eList];
	  v2[top].lastInList ← v2[top];
          };
       74  =>  -- MOEList  ::=		MOEList  ,  MOE
          {
	  temp2 ← TreesDefs.MakeNode[left: v2[top + 2], right: NIL,
	      string: NIL, nodeType: eList];
	  v2[top].lastInList.right ← temp2;
	  v2[top].lastInList ← temp2;
          };
       75  =>  -- MOE  ::=		NAME
          {
	  v2[top] ← TreesDefs.MakeNode[left: NIL, right: NIL,
	      string: v[top], nodeType: operation];
	  v2[top].operationType ← nameValue;
          };
       76  =>  -- MOE  ::=		NAME  =  e
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top + 2], right: NIL,
	      string: v[top], nodeType: operation];
	  v2[top].operationType ← nameValue;
          };
	  
	                --	COMPOUND STATEMENTS	--

        77  =>  -- DCmpStmt  ::=	Begin  RDclStatList  StmtList  }
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top + 1], right: v2[top + 2],
	      string: NIL, nodeType: compoundStmt];
          };

        78  =>  -- CmpStmt  ::=		Begin  StmtList  }
          {
	  v2[top] ← TreesDefs.MakeNode[left: NIL, right: v2[top + 1],
	      string: NIL, nodeType: compoundStmt];
          };

        79  =>  -- Begin  ::=		{
          NULL;
	  
	  
	  		--	EXPRESSION STATEMENTS	--

        80  =>   -- Stmt		::=	e   ;
          {
	  IF v2[top].operationType = postIncrement THEN
	      v2[top].operationType ← preIncrement
	  ELSE IF v2[top].operationType = postDecrement THEN
	      v2[top].operationType ← preDecrement;
	  v2[top] ← TreesDefs.MakeNode[left: v2[top], right: NIL,
	      string: NIL, nodeType: expressionStmt];
          };
        81  =>   -- Stmt		::=	CompoundStmt
	  NULL;
	  
	  		--	IF / THEN / ELSE STATEMENTS	--
			
        82  =>  -- Stmt  ::=	if  (  e  )  Stmt
          {
	  temp2 ← TreesDefs.MakeNode[left: v2[top + 4], right: NIL,
	      string: NIL, nodeType: thenElse];
	  v2[top] ← TreesDefs.MakeNode[left: v2[top + 2], right: temp2,
	      string: NIL, nodeType: ifStmt];
          };
        83  =>  -- Stmt  ::=	if  (  e  )  Stmt else  Stmt
          {
	  temp2 ← TreesDefs.MakeNode[left: v2[top + 4], right: v2[top + 6],
	      string: NIL, nodeType: thenElse];
	  v2[top] ← TreesDefs.MakeNode[left: v2[top + 2], right: temp2,
	      string: NIL, nodeType: ifStmt];
          };
	  
	  		--	LOOPING STATEMENTS	--
			
        84  =>  -- Stmt  ::=	while  (  e  )  Stmt
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top + 2], right: v2[top + 4],
	      string: NIL, nodeType: whileStmt];
          };
        85  =>  -- Stmt  ::=	do  Stmt  while  (  e  )   ;
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top + 4], right: v2[top + 1],
	      string: NIL, nodeType: doWhileStmt];
          };
        86  =>  -- ForPrefix  ::=  for  (  EOrEmpty  ;  EOrEmpty  ;
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top + 2], right: v2[top + 4],
	      string: NIL, nodeType: forStmt3];
          };
        87  =>  -- Stmt  ::=	ForPrefix  EOrEmpty  )  Stmt
          {
	  temp2 ← TreesDefs.MakeNode[left: v2[top + 1], right: v2[top],
	      string: NIL, nodeType: forStmt2];
	  v2[top] ← TreesDefs.MakeNode[left: v2[top + 3], right: temp2,
	      string: NIL, nodeType: forStmt1];
          };
	  
	  		--	SWITCH STATEMENT	--
			
        88  =>  -- Stmt  ::=	switch  (  e  )  Stmt
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top + 2], right: v2[top + 4],
	      string: NIL, nodeType: switchStmt];
          };
	  
	  		--	OTHER STATEMENTS	--
			
        89  =>  -- Stmt  ::=	break  ;
          {
	  v2[top] ← TreesDefs.MakeNode[left: NIL, right: NIL,
	      string: NIL, nodeType: breakStmt];
	  };
        90  =>  -- Stmt  ::=	continue  ;
          {
	  v2[top] ← TreesDefs.MakeNode[left: NIL, right: NIL,
	      string: NIL, nodeType: loopStmt];
	  };
        91  =>  -- Stmt  ::=	return  ;
          {
	  v2[top] ← TreesDefs.MakeNode[left: NIL, right: NIL,
	      string: NIL, nodeType: returnStmt];
	  };
        92  =>  -- Stmt  ::=	return e  ;
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top + 1], right: NIL,
	      string: NIL, nodeType: returnStmt];
          };
        93  =>  -- Stmt  ::=	goto  NAME  ;
          {
	  v2[top] ← TreesDefs.MakeNode[left: NIL, right: NIL,
	      string: v[top + 1], nodeType: gotoStmt];
          };
        94  =>  -- Stmt  ::=	;
          {
	  v2[top] ← TreesDefs.MakeNode[left: NIL, right: NIL,
	      string: NIL, nodeType: emptyStmt];
	  };
	  
	  		--	LABELS	--
			
        95  =>  -- Label  ::=		NAME  :
          {
	  v2[top] ← TreesDefs.MakeNode[left: NIL, right: NIL,
	      string: v[top], nodeType: labelLabel];
	  };
        96  =>  -- Label  ::=		case  e  :
          {
	  v2[top] ← TreesDefs.MakeNode[left: v2[top + 1], right: NIL,
	      string: NIL, nodeType: caseLabel];
	  };
        97  =>  -- Label  ::=		default  :
          {
	  v2[top] ← TreesDefs.MakeNode[left: NIL, right: NIL,
	      string: NIL, nodeType: defaultLabel];
	  };
	  
        ENDCASE => ERROR;
    };

  }.