options{ STATIC = false;  }

PARSER_BEGIN(TheParser)
  // No namespace needed here... but it's possible
  //   namespace myNameSpace;
  using System;
  using System.IO;

  // A few nested classes to make things simpler
  class TheParser{
     public static void Main(String[] args){
        Console.WriteLine(new TheParser(new StringReader("1 2 3 4 5"))
                              .parse_MainC());
     }

     // A Simple top-level class 
     public class MainC{
        public L lst;
        public MainC(L l){ lst = l; }
        public override String ToString(){ return "MainC: ("+lst+")"; }
     }

     // (L)ists
     public abstract class L{
        public abstract bool isEmpty();
     }
     // (E)mpty Lists
     public class E : L{
        public override String ToString(){ return ""; }
        public override bool isEmpty(){ return true; }
     }
     // (C)ons Lists
     public class C : L{
        public int f;
        public L r;
        public C(int ff, L rr){ f = ff; r = rr; }
        public override bool isEmpty(){ return false; }
        public override String ToString(){
           return f+(r.isEmpty()?"":", ")+r;
        }
     }
  }
PARSER_END(TheParser)

// So we don't have to deal with tokens...
int parse_int():{ Token t; }{
   t = <INT>
   { return Int32.Parse(t.image); }
}

// Parse a MainC
public MainC parse_MainC():{
     L lst;
}{
   lst = parse_L()
   { return new MainC(lst); }
}

// Parse a Cons/Empty List
public L parse_L():{
    L sup;
}{
 ( sup = parse_C()  { return sup; } | 
   sup = parse_E()  { return sup; } )
}

// Non-empty List
public C parse_C():{
     int f;
     L r;
}{
   f = parse_int()
   r = parse_L()
   { return new C(f,r); }
}

// Empty List
public E parse_E():{
}{
   { return new E(); }
}

// Lexer Definitions
SKIP : { " " | "\t" | "\n" | "\r" | "\r\n" }
SKIP : { <"//" (~["\n","\r"])* ("\n" | "\r\n")> }
SKIP : { <"/*" (~["*"])* "*" (~["/"] (~["*"])* "*")* "/">}
TOKEN: { < INT : ("+" | "-")?(["0"-"9"])+ > }