/*
** Copyright (c) 2007, Paul Cager
** All rights reserved.
** 
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
** 
**    * Redistributions of source code must retain the above copyright notice,
**      this list of conditions and the following disclaimer.
**    * Redistributions in binary form must reproduce the above copyright
**      notice, this list of conditions and the following disclaimer in the
**      documentation and/or other materials provided with the distribution.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
** THE POSSIBILITY OF SUCH DAMAGE.
*/

options { OUTPUT_DIRECTORY="out-dir"; }

PARSER_BEGIN(JavacodeTest)

/**
 *  A test to verify the interaction between JAVACODE
 *  productions and lookajead.
**/
public class JavacodeTest {

  public static void main(String args[]) throws Exception {
    JavacodeTest t = new JavacodeTest(System.in);
    System.out.print("Answer is: ");
    try {
      switch (args[0].charAt(0)) {
        case 'j': Javacode(); break;
        case 'n': NoJavacode(); break;
        case 'i': IndirectJavacode(); break;
        case 'I': IndirectJavacode2(); break;
        case 'N': JavacodeNoLa(); break;
      }
    } catch (Exception e) {
      System.out.println("Oops.");
      System.out.println(e.getMessage());
      throw(e);
    }
    System.out.println(".");
  }

  public static boolean isC() {
    return getToken(1).image.equals("C");
  }
}

PARSER_END(JavacodeTest)

TOKEN :
{
  < A: "A">
| < B: "B">
| < C: "C">
| < D: "D">
}

void Javacode() : {}
{
	(A() |  LOOKAHEAD( "C" ) javacode_method() | D() )*
	<EOF>
}

void JavacodeNoLa() : {}
{
	(A() | javacode_method() | D() )
	<EOF>
}

/*
* Similar non-javacode constructs are allowed. This checks a pointless
* (but legal) case.
*/
void NoJavacode() : {}
{
	(A() |  LOOKAHEAD( "C" ) B() | D() )*
	<EOF>
}

/*
* For semantic lookahead, the LA executes as expected (only
* succeeds if both the semantic and normal LA succeeds).
*/

void Semantic() : {}
{
	(A() | LOOKAHEAD( {isC()} ) B() | D() )*
	<EOF>
}

void IndirectJavacode() : {}
{
	( A() | Ind() | B() ) <EOF>
}

void IndirectJavacode2() : {}
{
	( A() | LOOKAHEAD("X") Ind() | B() ) <EOF>
}

void Ind() : {}
{
	javacode_method()
}

void A() : { }
{
	"A" { System.out.print("A"); }
}

void B() : { }
{
	"B" { System.out.print("B"); }
}

void C() : { }
{
	"C" { System.out.print("C"); }
}

void D() : { }
{
	"D" { System.out.print("D"); }
}

JAVACODE
void javacode_method() {
  Token t = getNextToken();
  System.out.print("javacode " + t.image);
 }
