/* Parser.js - changes control section

ID	Date	 Notes

*/
/********************************************************************

  Recursive Descent Parsing for the grammar:
  	E	->	let DL in E
	E	->	x Z
	Z	->	epsilon
	Z	->	(EL)
	EL	->	E W
	W	->	, EL
	W	->	epsilon
	DL	->	D Y
	Y	->	epsilon
	Y	->	DL
	D	->	oper x(LL)=E
	D	->	x = E
	LL	->	x X
	X	->	, LL
	X	->	epsilon

  There is a function for each of the non-terminals in the grammar.
  Each of these returns a node.

*********************************************************************/
var ParseError = '';

function SetParseError(s,t){
if (ParseError=='') ParseError=s+ 
                 " "+t[0]+" "+t[1]+" at line "+t[2];
}

function Parse_X(ts){
var a = Peek(ts);
if (a[1]==","){
  Get(ts);
  return(Parse_LL(ts));
  }
else
  return(0);
}

function Parse_LL(ts){
return(new Array("SEQ",Get(ts)[1],Parse_X(ts)));
}

function Parse_W(ts){
var a = Peek(ts);
if (a[1]==","){
  Get(ts);
  return(Parse_EL(ts));
  }
else
  return(0);
}

function Parse_EL(ts){
return(new Array("SEQ",Parse_E(ts), Parse_W(ts)));
}

function Parse_Y(ts){
var a = Peek(ts);
if (a[1]=="in")
  return(0);
else
  return(Parse_DL(ts));
}

function Parse_D(ts){
var a = Get(ts);
if (a[1]=="oper"){
  var x = Get(ts)[1];
  Get(ts);//left bracket
  var ll = Parse_LL(ts);
  Get(ts);//right bracket
  Get(ts);//equals
  var e = Parse_E(ts);
  return(new Array("DEF",x,new Array("LAMBDA",ll,e)));
  }
else{
  Get(ts);//equals
  var e = Parse_E(ts);
  return(new Array("DEF",a[1],e));
  }

}

function Parse_DL(ts){
var d = Parse_D(ts);
var y = Parse_Y(ts);
return(new Array("SEQ",d,y));
}

function Parse_Z(ts){
if (IsEmpty(ts))
  return(0);
var a = Peek(ts);
if ((a[0]=="SYMBOL") && (a[1]=="(")){
  Get(ts);
  var el = Parse_EL(ts);
  Get(ts);
  return(el);
  }
else
  return(0);
}

function checkNextIs(v,ts){
var a=Get(ts);
if (a[1]==v) {
  }
else {
  SetParseError("Was expecting "+v,a);
  }
}

function Parse_E(ts){
var a1 = Get(ts);
if (a1[0] == "LABEL"){
  if (a1[1]=="let") {
    var dl = Parse_DL(ts);
    checkNextIs("in",ts);
    var e = Parse_E(ts);
    return(new Array("LET",dl,e));
    }
  else{
    var z = Parse_Z(ts);
    if (z) 
      return(new Array("APP",a1[1],z));
    else {
      //alert('ok'+a1[1]);
      return(new Array("PRIM",a1[1]));
      }
    }
  }
else{
  SetParseError("in or LABEL expected",a1);
  return(0);
  }
}

function PPrint(a){
var i;
var x;
if (typeof(a)=="string")
  return a;
else {
  if ((!a)||(a.length==0))
    return("()");
  x="("+PPrint(a[0]);
  for (i=1;i<a.length;i++)
    x+=","+PPrint(a[i]);
  return(x+")");
  }
}



