options {
  STATIC = false;
  JAVA_UNICODE_ESCAPE = true;
}

PARSER_BEGIN(Parser)
import edu.neu.ccs.demeter.dj.*;
import edu.neu.ccs.demeter.*;
public class Parser { 
  // oit is uugly.  Why isn't there a Character.valueOf(String)? 
  static char unescapifyChar(String s) { 
    char c = s.charAt(0); 
    if (c == '\\') { 
      switch (s.charAt(1)) { 
      case 'n': c = '\n'; break; 
      case 't': c = '\t'; break; 
      case 'b': c = '\b'; break; 
      case 'r': c = '\r'; break; 
      case 'f': c = '\f'; break; 
      case '\\': c = '\\'; break; 
      case '\'': c = '\''; break; 
      case '\"': c = '\"'; break; 
      default: 
       c = (char) Integer.parseInt(s.substring(1, s.length()), 8); 
       break; 
      } 
    } 
    return c; 
  } 
  // Even uglier... 
  static String unescapify(String s) { 
    char str[] = new char[s.length()]; 
    int i = 0, o = 0; 
    while (i < s.length()) { 
      char c = s.charAt(i++); 
      if (c == '\\') { 
       int j = i + 1; 
       while (j < s.length() && 
              Character.digit(s.charAt(j), 8) != -1) { 
         j++; 
       } 
       c = unescapifyChar(s.substring(i-1, j)); 
       i = j; 
      } 
      str[o++] = c; 
    } 
    return String.valueOf(str, 0, o); 
  } 
} 

PARSER_END(Parser)

Blackboard _Blackboard() : {
  Blackboard it = null;
  Player_List _players;
  Store _store;
  Transaction_List _transactions;
  History _history;
} {
  { it=new Blackboard(); }
  "<Blackboard>"  "<Players>"  _players=_Player_List() { it.set_players(_players); }
  "</Players>"  _store=_Store() { it.set_store(_store); }
  "<Transactions>"  _transactions=_Transaction_List() { it.set_transactions(_transactions); }
  "</Transactions>"  _history=_History() { it.set_history(_history); }
  "</Blackboard>"  <EOF>
  { return it; }
}

Player _Player() : {
  Player it = null;
  PlayerName _name;
  Money _account;
  boolean _turn;
  PublicKey _publickey;
} {
  { it=new Player(); }
  "<Player>"  _name=_PlayerName() { it.set_name(_name); }
  "<Account>"  _account=_Money() { it.set_account(_account); }
  "</Account>"  "<Turn>"  _turn=_boolean() { it.set_turn(_turn); }
  "</Turn>"  [  _publickey=_PublicKey() { it.set_publickey(_publickey); }  ]
  "</Player>"  { return it; }
}

PlayerName _PlayerName() : {
  PlayerName it = null;
  String _v;
} {
  { it=new PlayerName(); }
  "<PlayerName>"  _v=_String() { it.set_v(_v); }
  "</PlayerName>"  { return it; }
}

PublicKey _PublicKey() : {
  PublicKey it = null;
} {
  { it=new PublicKey(); }
  "<PublicKey>"  "</PublicKey>"  { return it; }
}

History _History() : {
  History it = null;
  Transaction_EList _transaction_elist;
} {
  { it=new History(); }
  "<History>"  _transaction_elist=_Transaction_EList() { it.set_transaction_elist(_transaction_elist); }
  "</History>"  { return it; }
}

Transaction _Transaction() : {
  Transaction it = null;
} {
  ( it=_Buy() | it=_Create() | it=_DeliverR() | it=_Finish() )
  { return it; }
}

void common_Transaction(Transaction it) : {
} {
  { }
}

Buy _Buy() : {
  Buy it = null;
  PlayerName _playername;
  Derivative _derivative;
  DigitalSignature _digitalsignature;
} {
  { it=new Buy(); }
  "<Buy>"  _playername=_PlayerName() { it.set_playername(_playername); }
  _derivative=_Derivative() { it.set_derivative(_derivative); }
  [  _digitalsignature=_DigitalSignature() { it.set_digitalsignature(_digitalsignature); }  ]
  "</Buy>"  common_Transaction(it)
  { return it; }
}

Create _Create() : {
  Create it = null;
  PlayerName _playername;
  Derivative _derivative;
  DigitalSignature _digitalsignature;
} {
  { it=new Create(); }
  "<Create>"  _playername=_PlayerName() { it.set_playername(_playername); }
  _derivative=_Derivative() { it.set_derivative(_derivative); }
  [  _digitalsignature=_DigitalSignature() { it.set_digitalsignature(_digitalsignature); }  ]
  "</Create>"  common_Transaction(it)
  { return it; }
}

DeliverR _DeliverR() : {
  DeliverR it = null;
  PlayerName _playername;
  Derivative _derivative;
  DigitalSignature _digitalsignature;
} {
  { it=new DeliverR(); }
  "<Deliver>"  _playername=_PlayerName() { it.set_playername(_playername); }
  _derivative=_Derivative() { it.set_derivative(_derivative); }
  [  _digitalsignature=_DigitalSignature() { it.set_digitalsignature(_digitalsignature); }  ]
  "</Deliver>"  common_Transaction(it)
  { return it; }
}

Finish _Finish() : {
  Finish it = null;
  PlayerName _playername;
  Derivative _derivative;
  DigitalSignature _digitalsignature;
} {
  { it=new Finish(); }
  "<Finish>"  _playername=_PlayerName() { it.set_playername(_playername); }
  _derivative=_Derivative() { it.set_derivative(_derivative); }
  [  _digitalsignature=_DigitalSignature() { it.set_digitalsignature(_digitalsignature); }  ]
  "</Finish>"  common_Transaction(it)
  { return it; }
}

DigitalSignature _DigitalSignature() : {
  DigitalSignature it = null;
} {
  { it=new DigitalSignature(); }
  "<DigitalSignature>"  "</DigitalSignature>"  { return it; }
}

Store _Store() : {
  Store it = null;
  Derivative_EList _derivative_elist;
} {
  { it=new Store(); }
  "<Store>"  _derivative_elist=_Derivative_EList() { it.set_derivative_elist(_derivative_elist); }
  "</Store>"  { return it; }
}

Derivative _Derivative() : {
  Derivative it = null;
  DerivativeName _name;
  PlayerName _creator;
  Money _price;
  DerivativeType _type;
  PlayerName _boughtBy;
  RawMaterial _rawMaterial;
  FinishedProduct _finishedProduct;
} {
  { it=new Derivative(); }
  "<Derivative>"  _name=_DerivativeName() { it.set_name(_name); }
  "<Creator>"  _creator=_PlayerName() { it.set_creator(_creator); }
  "</Creator>"  "<Price>"  _price=_Money() { it.set_price(_price); }
  "</Price>"  _type=_DerivativeType() { it.set_type(_type); }
  [  "<BoughtBy>"  _boughtBy=_PlayerName() { it.set_boughtBy(_boughtBy); }  "</BoughtBy>"  ]
  [  _rawMaterial=_RawMaterial() { it.set_rawMaterial(_rawMaterial); }  ]
  [  _finishedProduct=_FinishedProduct() { it.set_finishedProduct(_finishedProduct); }  ]
  "</Derivative>"  { return it; }
}

FinishedProduct _FinishedProduct() : {
  FinishedProduct it = null;
  Assignment _assign;
  Money _quality;
} {
  { it=new FinishedProduct(); }
  "<FinishedProduct>"  _assign=_Assignment() { it.set_assign(_assign); }
  _quality=_Money() { it.set_quality(_quality); }
  "</FinishedProduct>"  { return it; }
}

DerivativeName _DerivativeName() : {
  DerivativeName it = null;
  String _name;
} {
  { it=new DerivativeName(); }
  "<DerivativeName>"  _name=_String() { it.set_name(_name); }
  "</DerivativeName>"  { return it; }
}

Money _Money() : {
  Money it = null;
  float _price;
} {
  { it=new Money(); }
  "<Money>"  _price=_float() { it.set_price(_price); }
  "</Money>"  { return it; }
}

DerivativeType _DerivativeType() : {
  DerivativeType it = null;
  ClauseType_List _clausetype_list;
} {
  { it=new DerivativeType(); }
  "<DerivativeType>"  _clausetype_list=_ClauseType_List() { it.set_clausetype_list(_clausetype_list); }
  "</DerivativeType>"  { return it; }
}

ClauseType _ClauseType() : {
  ClauseType it = null;
  TotalLiteralNum _total_num;
  PosLiteralNum _pos_num;
} {
  { it=new ClauseType(); }
  "<ClauseType>"  _total_num=_TotalLiteralNum() { it.set_total_num(_total_num); }
  _pos_num=_PosLiteralNum() { it.set_pos_num(_pos_num); }
  "</ClauseType>"  { return it; }
}

TotalLiteralNum _TotalLiteralNum() : {
  TotalLiteralNum it = null;
  Number _number;
} {
  { it=new TotalLiteralNum(); }
  "<TotalLiterals>"  _number=_Number() { it.set_number(_number); }
  "</TotalLiterals>"  { return it; }
}

PosLiteralNum _PosLiteralNum() : {
  PosLiteralNum it = null;
  Number _number;
} {
  { it=new PosLiteralNum(); }
  "<PosLiterals>"  _number=_Number() { it.set_number(_number); }
  "</PosLiterals>"  { return it; }
}

RawMaterial _RawMaterial() : {
  RawMaterial it = null;
  Clause_List _clause_list;
} {
  { it=new RawMaterial(); }
  "<RawMaterial>"  _clause_list=_Clause_List() { it.set_clause_list(_clause_list); }
  "</RawMaterial>"  { return it; }
}

Clause _Clause() : {
  Clause it = null;
  Weight _weight;
  Literal_List _literal_list;
} {
  { it=new Clause(); }
  "<Clause>"  _weight=_Weight() { it.set_weight(_weight); }
  "<Literals>"  _literal_list=_Literal_List() { it.set_literal_list(_literal_list); }
  "</Literals>"  "</Clause>"  { return it; }
}

Weight _Weight() : {
  Weight it = null;
  Number _weight;
} {
  { it=new Weight(); }
  "<Weight>"  _weight=_Number() { it.set_weight(_weight); }
  "</Weight>"  { return it; }
}

Literal _Literal() : {
  Literal it = null;
} {
  ( it=_PosLiteral() | it=_NegLiteral() )
  { return it; }
}

void common_Literal(Literal it) : {
} {
  { }
}

PosLiteral _PosLiteral() : {
  PosLiteral it = null;
  Variable _variable;
} {
  { it=new PosLiteral(); }
  "<PosLiteral>"  _variable=_Variable() { it.set_variable(_variable); }
  "</PosLiteral>"  common_Literal(it)
  { return it; }
}

NegLiteral _NegLiteral() : {
  NegLiteral it = null;
  Variable _variable;
} {
  { it=new NegLiteral(); }
  "<NegLiteral>"  _variable=_Variable() { it.set_variable(_variable); }
  "</NegLiteral>"  common_Literal(it)
  { return it; }
}

Variable _Variable() : {
  Variable it = null;
  Ident _v;
} {
  { it=new Variable(); }
  _v=_Ident() { it.set_v(_v); }
  { return it; }
}

Assignment _Assignment() : {
  Assignment it = null;
  Literal_List _literal_list;
} {
  { it=new Assignment(); }
  "<Assignment>"  _literal_list=_Literal_List() { it.set_literal_list(_literal_list); }
  "</Assignment>"  { return it; }
}

Quality _Quality() : {
  Quality it = null;
  float _v;
} {
  { it=new Quality(); }
  "<Quality>"  _v=_float() { it.set_v(_v); }
  "</Quality>"  { return it; }
}

Player_List _Player_List() : {
  Player_List it = null;
  Nonempty_Player_List _first;
} {
  { it=new Player_List(); }
  _first=_Nonempty_Player_List() { it.set_first(_first); }
  { return it; }
}

Transaction_List _Transaction_List() : {
  Transaction_List it = null;
  Nonempty_Transaction_List _first;
} {
  { it=new Transaction_List(); }
  _first=_Nonempty_Transaction_List() { it.set_first(_first); }
  { return it; }
}

Transaction_EList _Transaction_EList() : {
  Transaction_EList it = null;
  Nonempty_Transaction_EList _first;
} {
  { it=new Transaction_EList(); }
  [  _first=_Nonempty_Transaction_EList() { it.set_first(_first); }  ]
  { return it; }
}

Derivative_EList _Derivative_EList() : {
  Derivative_EList it = null;
  Nonempty_Derivative_EList _first;
} {
  { it=new Derivative_EList(); }
  [  _first=_Nonempty_Derivative_EList() { it.set_first(_first); }  ]
  { return it; }
}

ClauseType_List _ClauseType_List() : {
  ClauseType_List it = null;
  Nonempty_ClauseType_List _first;
} {
  { it=new ClauseType_List(); }
  _first=_Nonempty_ClauseType_List() { it.set_first(_first); }
  { return it; }
}

Clause_List _Clause_List() : {
  Clause_List it = null;
  Nonempty_Clause_List _first;
} {
  { it=new Clause_List(); }
  _first=_Nonempty_Clause_List() { it.set_first(_first); }
  { return it; }
}

Literal_List _Literal_List() : {
  Literal_List it = null;
  Nonempty_Literal_List _first;
} {
  { it=new Literal_List(); }
  _first=_Nonempty_Literal_List() { it.set_first(_first); }
  { return it; }
}

Nonempty_Player_List _Nonempty_Player_List() : {
  Nonempty_Player_List it = null;
  Player _it;
  Nonempty_Player_List _next;
} {
  { it=new Nonempty_Player_List(); }
  _it=_Player() { it.set_it(_it); }
  [  _next=_Nonempty_Player_List() { it.set_next(_next); }  ]
  { return it; }
}

Nonempty_Transaction_List _Nonempty_Transaction_List() : {
  Nonempty_Transaction_List it = null;
  Transaction _it;
  Nonempty_Transaction_List _next;
} {
  { it=new Nonempty_Transaction_List(); }
  _it=_Transaction() { it.set_it(_it); }
  [  _next=_Nonempty_Transaction_List() { it.set_next(_next); }  ]
  { return it; }
}

Nonempty_Transaction_EList _Nonempty_Transaction_EList() : {
  Nonempty_Transaction_EList it = null;
  Transaction _it;
  Nonempty_Transaction_EList _next;
} {
  { it=new Nonempty_Transaction_EList(); }
  _it=_Transaction() { it.set_it(_it); }
  [  _next=_Nonempty_Transaction_EList() { it.set_next(_next); }  ]
  { return it; }
}

Nonempty_Derivative_EList _Nonempty_Derivative_EList() : {
  Nonempty_Derivative_EList it = null;
  Derivative _it;
  Nonempty_Derivative_EList _next;
} {
  { it=new Nonempty_Derivative_EList(); }
  _it=_Derivative() { it.set_it(_it); }
  [  _next=_Nonempty_Derivative_EList() { it.set_next(_next); }  ]
  { return it; }
}

Nonempty_ClauseType_List _Nonempty_ClauseType_List() : {
  Nonempty_ClauseType_List it = null;
  ClauseType _it;
  Nonempty_ClauseType_List _next;
} {
  { it=new Nonempty_ClauseType_List(); }
  _it=_ClauseType() { it.set_it(_it); }
  [  _next=_Nonempty_ClauseType_List() { it.set_next(_next); }  ]
  { return it; }
}

Nonempty_Clause_List _Nonempty_Clause_List() : {
  Nonempty_Clause_List it = null;
  Clause _it;
  Nonempty_Clause_List _next;
} {
  { it=new Nonempty_Clause_List(); }
  _it=_Clause() { it.set_it(_it); }
  [  _next=_Nonempty_Clause_List() { it.set_next(_next); }  ]
  { return it; }
}

Nonempty_Literal_List _Nonempty_Literal_List() : {
  Nonempty_Literal_List it = null;
  Literal _it;
  Nonempty_Literal_List _next;
} {
  { it=new Nonempty_Literal_List(); }
  _it=_Literal() { it.set_it(_it); }
  [  _next=_Nonempty_Literal_List() { it.set_next(_next); }  ]
  { return it; }
}


boolean _boolean() : { Token t; }{
  ( t=<TRUE> { return true; }
  | t=<FALSE> { return false; }
  )
}

char _char() : { Token t; } {
    t=<CHARACTER_LITERAL> { 
       String s = t.image; 
       return unescapifyChar(s.substring(1, s.length()-1)); 
    } 
} 

byte _byte() : { int i; } 
{ i=_int() { return (byte) i; } } 

short _short() : { int i; } 
{ i=_int() { return (short) i; } } 

int _int() : { Number num; } 
{ num=_Number() { return num.intValue(); } } 

long _long() : { Number num; } 
{ num=_Number() { return num.longValue(); } } 

float _float() : { Number num; } 
{ num=_Number() { return num.floatValue(); } } 

double _double() : { Number num; } 
{ num=_Number() { return num.doubleValue(); } } 

Boolean _Boolean() : { Token t; }{
  ( t=<TRUE> { return Boolean.TRUE; }
  | t=<FALSE> { return Boolean.FALSE; }
  )
}

Character _Character() : { char c; } 
{ c=_char() { return new Character(c); } }

Integer _Integer() : { int i; } 
{ i = _int() { return new Integer(i); } }

Long _Long() : { long l; } 
{ l=_long() { return new Long(l); } } 

Float _Float() : { float f; } 
{ f=_float() { return new Float(f); } } 

Double _Double() : { double d; } 
{ d=_double() { return new Double(d); } } 

Number _Number() : 
{
    Token t; 
    String s = null; 
    int radix = 0; 
    Number num = null; 
} {
  ( 
    ( t=<DECIMAL_LITERAL> { 
       s = t.image; 
       radix = 10; 
      } 
    | t=<HEX_LITERAL> { 
       // Strip off the "0x". 
       s = t.image.substring(2, t.image.length()); 
       radix = 16; 
      } 
    | t=<OCTAL_LITERAL> { 
       s = t.image; 
       radix = 8; 
      } 
    ) { 
       switch (s.charAt(s.length()-1)) { 
       case 'l': case 'L': 
         s = s.substring(0, s.length()-1);
         num = new Long(new java.math.BigInteger(s, radix).longValue());
         break; 
       default: 
         num = new Integer(new java.math.BigInteger(s, radix).intValue());
         break; 
       } 
    } 
  | t=<FLOATING_POINT_LITERAL> { 
       s = t.image; 
       switch (s.charAt(s.length()-1)) { 
       case 'd': case 'D': 
           num = Double.valueOf(s.substring(0, s.length()-1)); 
           break; 
       case 'f': case 'F': 
           num = Float.valueOf(s.substring(0, s.length()-1)); 
           break; 
       default: 
           num = Float.valueOf(s); 
           break; 
       } 
    } 
  ) { return num; } 
} 

String _String() : { Token t; } {
    t=<STRING_LITERAL> { 
       String s = t.image; 
       return unescapify(s.substring(1, s.length()-1)); 
    } 
} 

StringBuffer _StringBuffer() : { String s; } 
{ s=_String() { return new StringBuffer(s); } }

Ident _Ident() : { Token t; } {
    t=<IDENTIFIER> { 
       return new Ident(t.image); 
    } 
} 

Text _Text() : { Token t; } {
    t=<TEXT_LITERAL> { 
       String s = t.image; 
       return new Text(s.substring(2, s.length()-2)); 
    } 
} 

Line _Line() : { Token t; } {
    { token_source.SwitchTo(1); } 
    t=<LINE> { 
       return new Line(t.image); 
    } 
} 

Word _Word() : { Token t; } {
    { token_source.SwitchTo(2); } 
    t=<WORD> { 
       return new Word(t.image); 
    } 
} 

// Lexical specification (largely taken from Java.jack): 

SKIP : {
  " " 
| "\t" 
| "\n" 
| "\r" 
| <"//" (~["\n","\r"])* ("\n"|"\r\n")> 
| <"/*" (~["*"])* "*" (~["/"] (~["*"])* "*")* "/"> 
} 
 
TOKEN : { /* LITERALS */
  < DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])* (["l","L"])? > 
| 
  < HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ (["l","L"])? > 
| 
  < OCTAL_LITERAL: "0" (["0"-"7"])* (["l","L"])? > 
| 
  < FLOATING_POINT_LITERAL: 
        (["0"-"9"])+ "." (["0"-"9"])+ (<EXPONENT>)? (["f","F","d","D"])? 
      | "." (["0"-"9"])+ (<EXPONENT>)? (["f","F","d","D"])? 
      | (["0"-"9"])+ <EXPONENT> (["f","F","d","D"])? 
      | (["0"-"9"])+ (<EXPONENT>)? ["f","F","d","D"] 
  > 
| 
  < #EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ > 
| 
  < CHARACTER_LITERAL: 
      "'" 
      (   (~["\'","\\","\n","\r"]) 
        | ("\\" 
            ( ["n","t","b","r","f","\\","\'","\""] 
            | ["0"-"7"] ( ["0"-"7"] )? 
            | ["0"-"3"] ["0"-"7"] ["0"-"7"] 
            ) 
          ) 
      ) 
      "'" 
  >   
| 
  < STRING_LITERAL: 
      "\"" 
      (   (~["\"","\\","\n","\r"]) 
        | ("\\" 
            ( ["n","t","b","r","f","\\","\'","\""] 
            | ["0"-"7"] ( ["0"-"7"] )? 
            | ["0"-"3"] ["0"-"7"] ["0"-"7"] 
            ) 
          ) 
      )* 
      "\"" 
  > 
| 
  < TEXT_LITERAL: 
     ( "(@" 
           (~["@"])* 
           ( "@" ~[")"] 
             (~["@"])* 
           )* 
      "@)" ) 
    | ( "{{" 
           (~["}"])* 
           ( "}" ~["}"] 
             (~["}"])* 
           )* 
      "}}" ) 
  > 
| 
  < TRUE: "true" >
| 
  < FALSE: "false" >
} 

TOKEN : { /* IDENTIFIERS */ 
  < IDENTIFIER: <LETTER> (<LETTER>|<DIGIT>)* >
|
  < #LETTER:
      [
       "\u0024",
       "\u0041"-"\u005a",
       "\u005f",
       "\u0061"-"\u007a",
       "\u00c0"-"\u00d6",
       "\u00d8"-"\u00f6",
       "\u00f8"-"\u00ff",
       "\u0100"-"\u1fff",
       "\u3040"-"\u318f",
       "\u3300"-"\u337f",
       "\u3400"-"\u3d2d",
       "\u4e00"-"\u9fff",
       "\uf900"-"\ufaff"
      ]
  >
|
  < #DIGIT:
      [
       "\u0030"-"\u0039",
       "\u0660"-"\u0669",
       "\u06f0"-"\u06f9",
       "\u0966"-"\u096f",
       "\u09e6"-"\u09ef",
       "\u0a66"-"\u0a6f",
       "\u0ae6"-"\u0aef",
       "\u0b66"-"\u0b6f",
       "\u0be7"-"\u0bef",
       "\u0c66"-"\u0c6f",
       "\u0ce6"-"\u0cef",
       "\u0d66"-"\u0d6f",
       "\u0e50"-"\u0e59",
       "\u0ed0"-"\u0ed9",
       "\u1040"-"\u1049"
      ]
  >
}

<Line> TOKEN : {
  < LINE: (~["\n","\r"])* > : DEFAULT
}

<Word> SKIP :  { " " | "\t" | "\n" | "\r" }
<Word> TOKEN : {
  < WORD: (~[" ","\t","\n","\r"])* > : DEFAULT
}