options {
  STATIC = false;
  JAVA_UNICODE_ESCAPE = true;
}

PARSER_BEGIN(Parser)
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)

TraversalDef _TraversalDef() : {
  TraversalDef it = null;
  TraversalName _tn;
  Itinerary _rhs;
} {
  { it=new TraversalDef(); }
  _tn=_TraversalName() { it.set_tn(_tn); }
  "="  _rhs=_Itinerary() { it.set_rhs(_rhs); }
  { return it; }
}

TraversalName _TraversalName() : {
  TraversalName it = null;
  Ident _ident;
} {
  { it=new TraversalName(); }
  _ident=_Ident() { it.set_ident(_ident); }
  { return it; }
}

Itinerary _Itinerary() : {
  Itinerary it = null;
  Nonempty_Itinerary _first;
} {
  { it=new Itinerary(); }
  "{"  _first=_Nonempty_Itinerary() { it.set_first(_first); }
  "};"  { return it; }
}

Path _Path() : {
  Path it = null;
} {
  ( it=_Direct() | it=_Bypass() )
  { return it; }
}

void common_Path(Path it) : {
} {
  { }
}

Direct _Direct() : {
  Direct it = null;
} {
  ============================================ Line 96 ===========================
  ( it=_Tag() | it=_NoTag() )
  { return it; }
}

void common_Direct(Direct it) : {
} {
  common_Path(it)
  { }
}

NoTag _NoTag() : {
  NoTag it = null;
  SNode _snode;
  TNode _tnode;
} {
  { it=new NoTag(); }
  _snode=_SNode() { it.set_snode(_snode); }
  "->"  _tnode=_TNode() { it.set_tnode(_tnode); }
  common_Direct(it)
  { return it; }
}

Tag _Tag() : {
  Tag it = null;
} {
  ( it=_SourceTag() | it=_TarTag() )
  { return it; }
}

void common_Tag(Tag it) : {
} {
  common_Direct(it)
  { }
}

SourceTag _SourceTag() : {
  SourceTag it = null;
  SNode _snode;
  TNode _tnode;
} {
  { it=new SourceTag(); }
  "source:"  _snode=_SNode() { it.set_snode(_snode); }
  "->"  _tnode=_TNode() { it.set_tnode(_tnode); }
  common_Tag(it)
  { return it; }
}

TarTag _TarTag() : {
  TarTag it = null;
  SNode _snode;
  TNode _tnode;
} {
  { it=new TarTag(); }
  _snode=_SNode() { it.set_snode(_snode); }
  "->target:"  _tnode=_TNode() { it.set_tnode(_tnode); }
  common_Tag(it)
  { return it; }
}

Bypass _Bypass() : {
  Bypass it = null;
  Nonempty_Bypass _first;
} {
  { it=new Bypass(); }
  "bypassing {"  _first=_Nonempty_Bypass() { it.set_first(_first); }
  "}"  common_Path(it)
  { return it; }
}

SNode _SNode() : {
  SNode it = null;
  Ident _ident;
} {
  { it=new SNode(); }
  _ident=_Ident() { it.set_ident(_ident); }
  { return it; }
}

TNode _TNode() : {
  TNode it = null;
  Ident _ident;
} {
  { it=new TNode(); }
  _ident=_Ident() { it.set_ident(_ident); }
  { return it; }
}

Node _Node() : {
  Node it = null;
  Ident _ident;
} {
  { it=new Node(); }
  _ident=_Ident() { it.set_ident(_ident); }
  { return it; }
}

Main _Main() : {
  Main it = null;
  TraversalDef _tdef;
} {
  { it=new Main(); }
  _tdef=_TraversalDef() { it.set_tdef(_tdef); }
  { return it; }
}

Nonempty_Itinerary _Nonempty_Itinerary() : {
  Nonempty_Itinerary it = null;
  Path _it;
  Nonempty_Itinerary _next;
} {
  { it=new Nonempty_Itinerary(); }
  _it=_Path() { it.set_it(_it); }
  [  _next=_Nonempty_Itinerary() { it.set_next(_next); }  ]
  { return it; }
}

Nonempty_Bypass _Nonempty_Bypass() : {
  Nonempty_Bypass it = null;
  Node _it;
  Nonempty_Bypass _next;
} {
  { it=new Nonempty_Bypass(); }
  _it=_Node() { it.set_it(_it); }
  [  _next=_Nonempty_Bypass() { 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
}