/*
* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of the License "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description: 
*
*/
/* Generated By:JavaCC: Do not edit this line. BldInfParserCore.java */
package com.nokia.carbide.internal.cpp.epoc.engine.parser.generated;

import com.nokia.carbide.internal.api.cpp.epoc.engine.dom.*;
import com.nokia.carbide.internal.api.cpp.epoc.engine.dom.bldinf.*;
import com.nokia.carbide.internal.cpp.epoc.engine.parser.*;
import com.nokia.carbide.internal.cpp.epoc.engine.parser.bldinf.*;

import java.util.*;

// these must exactly match the keywords used in bld.inf (minus leading PRJ_)
enum BldInfBlock {
        NONE,
        PLATFORMS,
        MMPFILES,
        TESTMMPFILES,
        EXPORTS,
        TESTEXPORTS,
        EXTENSIONS,
        TESTEXTENSIONS
};

public class BldInfParserCore extends ParserBase implements BldInfParserCoreConstants {
        BldInfBlock currentBlock;
        IASTBldInfBlockStatement currentBlockStmt;
        Token currentBlockLast;
        Map<Integer, BldInfBlock> blockMap;
        IASTBldInfTranslationUnit tu;
        int blockDepth;

    public IASTBldInfTranslationUnit parse() {
                currentBlock = BldInfBlock.NONE;
                currentBlockStmt = null;
                currentBlockLast = null;
        this.blockMap = new HashMap<Integer, BldInfBlock>();
        this.blockDepth = 0;

                tu = ASTBldInfFactory.createBldInfTranslationUnit();
                try {
                        TranslationUnit(tu);
                } catch (ParseException e) {
                        hadErrors = true;
                        e.printStackTrace();
                }
                return tu;
    }

  final public void TranslationUnit(IASTBldInfTranslationUnit tu) throws ParseException {
        IASTListNode<IASTBldInfStatement> statements = ASTBldInfFactory.createBldInfStatementListNode();
        Token eof;
    Statements(statements);
    eof = jj_consume_token(0);
                finishCurrentBlock();
                if (statements != null) {
                        tu.setNodes((IASTListNode)statements);
                        ParserUtils.setSourceRangeForListNode(null, tu.getNodes(), eof);
                        ParserUtils.copySourceInfo(tu, tu.getNodes());
                } else {
                        ParserUtils.setSourceRangeFromTokenSpan(tu.getNodes(), eof, eof);
                        ParserUtils.setSourceRangeFromTokenSpan(tu, eof, eof);
                }
  }

  void Statements(IASTListNode<IASTBldInfStatement> stmts) throws ParseException {
        do {
                Statement(stmts);
        } while (token.kind != EOF);
  }

  IASTBldInfStatement createProblemStatement(Token start, Token end, ParseException e) throws ParseException {
        IASTBldInfStatement stmt;

        if (end == null) {
                ppRestOfLine(false);
                end = token;
        }
        List<IToken> tokens = new ArrayList<IToken>();
        start = start.next;
        while (true) {
                if (start.kind == EOF)
                        break;
                tokens.add(((ASTToken)start).iToken);
                if (start == end)
                        break;
                start = start.next;
        }
        IASTPreprocessorTokenStream stream = ASTFactory.createPreprocessorTokenStream(tokens);
        ParserUtils.setSourceRangeForTokenStream(stream, stream);
        stmt = ASTBldInfFactory.createBldInfProblemStatement(stream, createMessage(start, e));
        ParserUtils.copySourceInfo(stmt, stream);

        hadErrors = true;
        return stmt;
  }

  final public void Statement(IASTListNode<IASTBldInfStatement> statements) throws ParseException {
        Token start = token;
        IASTBldInfStatement node;
    try {
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case PRJ_PLATFORMS:
      case PRJ_MMPFILES:
      case PRJ_TESTMMPFILES:
      case PRJ_EXPORTS:
      case PRJ_TESTEXPORTS:
      case PRJ_EXTENSIONS:
      case PRJ_TESTEXTENSIONS:
        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
        case PRJ_PLATFORMS:
          node = PrjPlatformsStatement();
          break;
        case PRJ_MMPFILES:
        case PRJ_TESTMMPFILES:
          node = PrjMmpfilesStatement();
          break;
        case PRJ_EXPORTS:
        case PRJ_TESTEXPORTS:
          node = PrjExportsStatement();
          break;
        case PRJ_EXTENSIONS:
        case PRJ_TESTEXTENSIONS:
          node = PrjExtensionsStatement();
          break;
        default:
          jj_la1[0] = jj_gen;
          jj_consume_token(-1);
          throw new ParseException();
        }
                        statements.add(node);
        break;
      case BLOCK_ENTER:
        jj_consume_token(BLOCK_ENTER);
                        resyncCurrentStatement(statements, 1);
        break;
      case BLOCK_SWITCH:
        jj_consume_token(BLOCK_SWITCH);
                        resyncCurrentStatement(statements, 0);
        break;
      case BLOCK_EXIT:
        jj_consume_token(BLOCK_EXIT);
                        resyncCurrentStatement(statements, -1);
        break;
      case EOL:
        node = Empty();

        break;
      default:
        jj_la1[1] = jj_gen;
        CurrentBlockStatement(statements);

      }
    } catch (ParseException e) {
                statements.add(createProblemStatement(start, null, e));
    }
  }

  void CurrentBlockStatement(IASTListNode<IASTBldInfStatement> statements) throws ParseException {
          int t = (jj_ntk==-1)?jj_ntk():jj_ntk;
        if (t == EOF || t == EOL || t == BLOCK_ENTER || t == BLOCK_SWITCH || t == BLOCK_EXIT) {
                token = getNextToken();
                return;
        }
        //System.out.println("current statement parsed for block " + currentBlock);

        if (currentBlock == BldInfBlock.NONE) {
                Token start = token;
                IASTLiteralTextNode node = Argument();
                statements.add(createProblemStatement(start, null,
                        new ParseException("Unexpected section keyword: " + node.getValue())));
                return;
        }

        if (currentBlock == BldInfBlock.PLATFORMS) {
                IASTLiteralTextNode platform = ArgumentOrNewline();
                if (platform != null) {
                        currentBlockStmt.getList().add(platform);
                }
        } else if (currentBlock == BldInfBlock.MMPFILES || currentBlock == BldInfBlock.TESTMMPFILES) {
                IASTBldInfMakMakeStatement makmake = MakmakeStatement();
                if (makmake != null) {
                        statements.add(makmake);
                }
        } else if (currentBlock == BldInfBlock.EXPORTS || currentBlock == BldInfBlock.TESTEXPORTS) {
                IASTBldInfExportStatement export = Export();
                if (export != null) {
                        statements.add(export);
                }
        } else if (currentBlock == BldInfBlock.EXTENSIONS || currentBlock == BldInfBlock.TESTEXTENSIONS) {
                IASTBldInfExtensionBlockStatement ext = ExtensionBlockStatement();
                if (ext != null) {
                        statements.add(ext);
                }
        } else {
                throw new ParseException("Unhandled block: "+ currentBlock);
        }
  }

  void setCurrentConditionalBlock() throws ParseException, ParseException {
        //System.out.println("updating block " + blockDepth + " to " + currentBlock);
          blockMap.put(blockDepth, currentBlock);
  }

  void resyncCurrentStatement(IASTListNode<IASTBldInfStatement> statements, int delta) throws ParseException, ParseException {
  if (delta > 0) {
           blockDepth += delta;
        //System.out.println("handling delta " + delta + " to depth " + blockDepth);
                blockMap.put(blockDepth, currentBlock);
                return;
  } else  {
                BldInfBlock prevBlock;
                if (delta < 0) {
                        prevBlock = blockMap.get(blockDepth);
                        blockDepth += delta;
                } else {
                        prevBlock = blockMap.get(blockDepth - 1);
                }
                //System.out.println("resyncing to depth " + outerDepth);
                  if (prevBlock != null && prevBlock != currentBlock) {
                                finishCurrentBlock();
                          IASTBldInfStatement stmt = setCurrentBlock(prevBlock, null, null);
                          if (stmt != null) {
                                        /*
				  // set the source info from the last statement of this type
				  IASTBldInfStatement prev = null;
				  for (IASTBldInfStatement lastStmt : statements) {
				  	if (lastStmt.getKeywordName().equalsIgnoreCase(stmt.getKeywordName())) {
				  		prev = lastStmt;
				  		break;
				  	}
				  }
					if (prev != null) {
						ParserUtils.setSourceRangeAfterNode(((IASTBldInfBlockStatement)stmt).getKeyword(), prev);
						ParserUtils.setSourceRangeAfterNode(stmt, prev);
					} else {
						ParserUtils.setSourceRangeFromTokenSpanUpTo(((IASTBldInfBlockStatement)stmt).getKeyword(), token, token);
						ParserUtils.setSourceRangeFromTokenSpanUpTo(stmt, token, token);
					}
					*/
                                  statements.add(stmt);
                          }
                  }
                 }
  }

  IASTBldInfBlockStatement setCurrentBlock(BldInfBlock blockType, IASTBldInfBlockStatement blockStmt, Token lastToken) throws ParseException {
        //System.out.println("Set block type to " +blockType);
        if (blockType == BldInfBlock.NONE)
                return null;
        currentBlock = blockType;
        currentBlockLast = lastToken;
        if (blockStmt == null) {
                blockStmt = ASTBldInfFactory.createBldInfBlockStatement("PRJ_" + blockType.toString());
                if (lastToken != null) {
                        ParserUtils.setSourceRangeFromTokenSpanUpTo(blockStmt, lastToken, lastToken);
                        ParserUtils.expandSourceRangeToLine(blockStmt);
                }
    }
        currentBlockStmt = blockStmt;
        setCurrentConditionalBlock();
        return currentBlockStmt;
  }

  void finishCurrentBlock() throws ParseException {
        if (currentBlock == BldInfBlock.EXTENSIONS)
                ((BldInfTokenManager)token_source).setInExtension(false);

        if (currentBlock == BldInfBlock.NONE)
                return;

        // NOTE: the block statement's list is only used for PRJ_PLATFORMS.
        // Other PRJ_xxx statements place their nodes in the top level.
        if (currentBlockStmt.getList().isEmpty()) {
                Token tok = currentBlockLast != null ? currentBlockLast : token;
                if (tok != null) {
                        ParserUtils.setSourceRangeFromTokenAfter(currentBlockStmt.getList(), tok);
                }
        } else {
                ParserUtils.setSourceRangeForListNode(null, currentBlockStmt.getList(), null);
                ParserUtils.setAdjacentSourceRangesForListElements(currentBlockStmt.getList());
        }
        if (currentBlockStmt.getSourceRegion() != null) {
                ParserUtils.extendSourceRangeToInclude(currentBlockStmt, currentBlockStmt.getList());
                ParserUtils.expandSourceRangeToLine(currentBlockStmt);
        } else {
                // the block was created in a re-sync and needs to be set from its list
                ParserUtils.copySourceInfo(currentBlockStmt, currentBlockStmt.getList());
                ParserUtils.setSourceRangeFromTokenSpanUpTo(((IASTBldInfBlockStatement)currentBlockStmt).getKeyword(), token, token);
        }

        currentBlock = BldInfBlock.NONE;
        currentBlockStmt = null;
  }

  final public IASTBldInfStatement PrjPlatformsStatement() throws ParseException {
        IASTBldInfStatement node;
        Token start;
        Token eol = null;
          finishCurrentBlock();
    start = jj_consume_token(PRJ_PLATFORMS);
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case EOL:
      eol = jj_consume_token(EOL);
      break;
    default:
      jj_la1[2] = jj_gen;
      ;
    }
                node = setCurrentBlock(BldInfBlock.PLATFORMS,
                                                ASTBldInfFactory.createBldInfPrjPlatformsBlockStatement(
                                                        getLiteralTextNodeSpanning(start, start), null),
                                                eol != null ? eol : start);
                ParserUtils.setSourceRangeFromTokenSpan(node, start, eol != null ? eol : start);
                ParserUtils.setSourceRangeFromTokenAfter(((IASTBldInfPrjPlatformsBlockStatement)node).getList(), start);
                {if (true) return node;}
    throw new Error("Missing return statement in function");
  }

  final public IASTBldInfStatement PrjMmpfilesStatement() throws ParseException {
        IASTBldInfStatement node;
        Token start;
        Token eol;
          finishCurrentBlock();
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case PRJ_MMPFILES:
      start = jj_consume_token(PRJ_MMPFILES);
      break;
    case PRJ_TESTMMPFILES:
      start = jj_consume_token(PRJ_TESTMMPFILES);
      break;
    default:
      jj_la1[3] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
    eol = jj_consume_token(EOL);
                node = setCurrentBlock(
                                                (start.image.equalsIgnoreCase("PRJ_MMPFILES") ? BldInfBlock.MMPFILES : BldInfBlock.TESTMMPFILES),
                                                ASTBldInfFactory.createBldInfPrjMmpfilesBlockStatement(
                                                        getLiteralTextNodeSpanning(start, start), null),
                                                eol);
                ParserUtils.setSourceRangeFromTokenSpan(node, start, start);
                {if (true) return node;}
    throw new Error("Missing return statement in function");
  }

  final public IASTBldInfMakMakeStatement MakmakeStatement() throws ParseException {
        IASTBldInfMakMakeStatement stmt = null;
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case GNUMAKEFILE:
    case NMAKEFILE:
    case MAKEFILE:
      stmt = Makefile();
      break;
    case ARGUMENT:
      stmt = Mmpfile();
      break;
    case EOL:
      Empty();
      break;
    default:
      jj_la1[4] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
                {if (true) return stmt;}
    throw new Error("Missing return statement in function");
  }

  final public IASTBldInfMakMakeStatement Mmpfile() throws ParseException {
        IASTBldInfMakMakeStatement stmt;
        Token eol;
        IASTLiteralTextNode filename;
        IASTListNode<IASTLiteralTextNode> attributes = null;
    filename = Argument();
    attributes = Arguments();
    eol = jj_consume_token(EOL);
                stmt = ASTBldInfFactory.createBldInfMmpfileStatement(
                        filename,
                        attributes);
                if (attributes.size() > 0)
                        ParserUtils.setSourceRangeForListNode(null, attributes, eol);
                else
                ParserUtils.setSourceRangeFromTokenSpanUpTo(attributes, eol, eol);

                ParserUtils.copySourceInfo(stmt, filename);
                ParserUtils.extendSourceRangeToInclude(stmt, eol);
                ParserUtils.expandSourceRangeToLine(stmt);
                {if (true) return stmt;}
    throw new Error("Missing return statement in function");
  }

  final public IASTBldInfMakefileStatement Makefile() throws ParseException {
        IASTBldInfMakefileStatement stmt;
        Token type;
        Token eol;
        IASTLiteralTextNode filename;
        IASTListNode<IASTLiteralTextNode> attributes = null;
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case GNUMAKEFILE:
      type = jj_consume_token(GNUMAKEFILE);
      break;
    case NMAKEFILE:
      type = jj_consume_token(NMAKEFILE);
      break;
    case MAKEFILE:
      type = jj_consume_token(MAKEFILE);
      break;
    default:
      jj_la1[5] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
    filename = Argument();
    attributes = Arguments();
    eol = jj_consume_token(EOL);
                stmt = ASTBldInfFactory.createBldInfMakefileStatement(
                        getLiteralTextNodeSpanning(type, type),
                        filename,
                        attributes);
                if (attributes.size() > 0)
                        ParserUtils.setSourceRangeForListNode(null, attributes, eol);
                else
                ParserUtils.setSourceRangeFromTokenSpanUpTo(attributes, eol, eol);
                ParserUtils.setSourceRangeFromTokenSpan(stmt, type, eol);
                ParserUtils.expandSourceRangeToLine(stmt);
                {if (true) return stmt;}
    throw new Error("Missing return statement in function");
  }

  final public IASTBldInfStatement PrjExportsStatement() throws ParseException {
        IASTBldInfStatement node;
        Token start;
        Token eol;
          finishCurrentBlock();
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case PRJ_EXPORTS:
      start = jj_consume_token(PRJ_EXPORTS);
      break;
    case PRJ_TESTEXPORTS:
      start = jj_consume_token(PRJ_TESTEXPORTS);
      break;
    default:
      jj_la1[6] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
    eol = jj_consume_token(EOL);
                node = setCurrentBlock(
                                                (start.image.equalsIgnoreCase("PRJ_EXPORTS") ? BldInfBlock.EXPORTS : BldInfBlock.TESTEXPORTS),
                                                ASTBldInfFactory.createBldInfPrjExportsBlockStatement(
                                                        getLiteralTextNodeSpanning(start, start), null),
                                                eol);
                ParserUtils.setSourceRangeFromTokenSpan(node, start, start);
                ParserUtils.extendSourceRangeToInclude(node, eol);
                ParserUtils.expandSourceRangeToLine(node);
                {if (true) return node;}
    throw new Error("Missing return statement in function");
  }

  final public IASTBldInfExportStatement Export() throws ParseException {
        IASTBldInfExportStatement stmt;
        Token zip = null, eol;
        IASTLiteralTextNode source, target = null;
        IASTListNode<IASTLiteralTextNode> targetList = null;
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case ZIP:
    case ARGUMENT:
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case ZIP:
        zip = jj_consume_token(ZIP);
        break;
      default:
        jj_la1[7] = jj_gen;
        ;
      }
      source = Argument();
      targetList = Arguments();
      eol = jj_consume_token(EOL);
                if (targetList != null && targetList.size() > 0) {
                        if (targetList.size() == 1) {
                                target = targetList.get(0);
                                target.setParent(null);
                        } else {
                                target = ASTFactory.createPreprocessorLiteralTextNode(targetList.getOriginalText());
                                ParserUtils.copySourceInfo(target, targetList);
                        }
                }
                stmt = ASTBldInfFactory.createBldInfExportStatement(
                        source, target,
                        getLiteralTextNodeSpanning(zip, zip));
                ParserUtils.copySourceInfo(stmt, source);
                if (zip != null)
                        ParserUtils.extendSourceRangeToInclude(stmt, zip);
                ParserUtils.extendSourceRangeToInclude(stmt, eol);
                ParserUtils.expandSourceRangeToLine(stmt);
                {if (true) return stmt;}
      break;
    case EOL:
      jj_consume_token(EOL);
                {if (true) return null;}
      break;
    default:
      jj_la1[8] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
    throw new Error("Missing return statement in function");
  }

  final public IASTBldInfStatement PrjExtensionsStatement() throws ParseException {
        IASTBldInfStatement node;
        Token start;
        Token eol;
          finishCurrentBlock();
          ((BldInfTokenManager)token_source).setInExtension(true);
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case PRJ_EXTENSIONS:
      start = jj_consume_token(PRJ_EXTENSIONS);
      break;
    case PRJ_TESTEXTENSIONS:
      start = jj_consume_token(PRJ_TESTEXTENSIONS);
      break;
    default:
      jj_la1[9] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
    eol = jj_consume_token(EOL);
                node = setCurrentBlock(
                                                (start.image.equalsIgnoreCase("PRJ_EXTENSIONS")
                                                        ? BldInfBlock.EXTENSIONS : BldInfBlock.TESTEXTENSIONS),
                                                ASTBldInfFactory.createBldInfPrjExtensionsBlockStatement(
                                                        getLiteralTextNodeSpanning(start, start), null),
                                                eol);
                ParserUtils.setSourceRangeFromTokenSpan(node, start, start);
                ParserUtils.extendSourceRangeToInclude(node, eol);
                ParserUtils.expandSourceRangeToLine(node);
                {if (true) return node;}
    throw new Error("Missing return statement in function");
  }

  final public IASTBldInfExtensionBlockStatement ExtensionBlockStatement() throws ParseException {
        IASTBldInfExtensionBlockStatement stmt;
        IASTListNode<IASTLiteralTextNode> args;
        IASTListNode<IASTBldInfExtensionStatement> stmts;
        Token start, end, eol;
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case START:
      start = jj_consume_token(START);
      args = Arguments();
      eol = jj_consume_token(EOL);
      stmts = ExtensionStatements();
      end = jj_consume_token(END);
                if (stmts == null) {
                        stmts = ASTBldInfFactory.createBldInfExtensionStatementList();
                        ParserUtils.setSourceRangeFromTokenSpan(stmts, end, end);
                } else {
                        ParserUtils.setSourceRangeForListNode(null, stmts, null);
                        ParserUtils.setAdjacentSourceRangesForListElements(stmts);
                }
                if (stmts.isEmpty())
                        ParserUtils.extendSourceRangeToInclude(args, eol);
                stmt = ASTBldInfFactory.createBldInfExtensionBlockStatement(
                        args, stmts);
                ParserUtils.setSourceRangeFromTokenSpan(stmt.getKeyword(), start, start);
                ParserUtils.setSourceRangeFromTokenSpan(stmt, start, end);
                ParserUtils.expandSourceRangeToLine(stmt);
                {if (true) return stmt;}
      break;
    case EOL:
      jj_consume_token(EOL);
                {if (true) return null;}
      break;
    default:
      jj_la1[10] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
    throw new Error("Missing return statement in function");
  }

  final public IASTListNode<IASTBldInfExtensionStatement> ExtensionStatements() throws ParseException {
        IASTBldInfExtensionStatement stmt;
        IASTListNode<IASTBldInfExtensionStatement> tail = null;
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case BLOCK_ENTER:
    case BLOCK_SWITCH:
    case BLOCK_EXIT:
    case EOL:
    case ARGUMENT:
      stmt = Extension();
      tail = ExtensionStatements();
                if (stmt != null) {
                        if (tail == null)
                                tail = ASTBldInfFactory.createBldInfExtensionStatementList();

                        tail.add(0, stmt);
                }
                {if (true) return tail;}
      break;
    default:
      jj_la1[11] = jj_gen;
                {if (true) return null;}
    }
    throw new Error("Missing return statement in function");
  }

  final public IASTBldInfExtensionStatement Extension() throws ParseException {
        IASTBldInfExtensionStatement stmt;
        IASTLiteralTextNode keyword = null;
        IASTListNode<IASTLiteralTextNode> args = null;
        Token eol;
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case ARGUMENT:
      keyword = Argument();
      args = Arguments();
      eol = jj_consume_token(EOL);
                stmt = ASTBldInfFactory.createBldInfExtensionStatement(
                        keyword, args);
                ParserUtils.setSourceRangeFromNodes(stmt, keyword, keyword); // not args since it may be empty
                ParserUtils.extendSourceRangeToInclude(stmt, eol);
                ParserUtils.expandSourceRangeToLine(stmt);
                {if (true) return stmt;}
      break;
    case BLOCK_ENTER:
    case BLOCK_SWITCH:
    case BLOCK_EXIT:
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case BLOCK_ENTER:
        jj_consume_token(BLOCK_ENTER);
        break;
      case BLOCK_SWITCH:
        jj_consume_token(BLOCK_SWITCH);
        break;
      case BLOCK_EXIT:
        jj_consume_token(BLOCK_EXIT);
        break;
      default:
        jj_la1[12] = jj_gen;
        jj_consume_token(-1);
        throw new ParseException();
      }
                {if (true) return null;}
      break;
    case EOL:
      jj_consume_token(EOL);
                {if (true) return null;}
      break;
    default:
      jj_la1[13] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
    throw new Error("Missing return statement in function");
  }

  final public IASTLiteralTextNode Argument() throws ParseException {
        Token token = null;
    token = jj_consume_token(ARGUMENT);
                {if (true) return getLiteralTextNodeSpanning(token, token);}
    throw new Error("Missing return statement in function");
  }

  final public IASTListNode<IASTLiteralTextNode> Arguments() throws ParseException {
        IASTLiteralTextNode arg = null;
        IASTListNode<IASTLiteralTextNode> args = null;
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case ARGUMENT:
      args = ArgumentList();
      break;
    default:
      jj_la1[14] = jj_gen;
      ;
    }
                if (args == null) {
                        args = ASTFactory.createLiteralTextNodeList();
                        args.setSeparator(" ");
                }
                if (arg != null)
                        args.add(0, arg);
                ParserUtils.setSourceRangeForListNode(null, args, null);
                {if (true) return args;}
    throw new Error("Missing return statement in function");
  }

  final public IASTListNode<IASTLiteralTextNode> ArgumentList() throws ParseException {
        IASTLiteralTextNode arg = null;
        IASTListNode<IASTLiteralTextNode> args = null;
    arg = Argument();
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case ARGUMENT:
      args = ArgumentList();
      break;
    default:
      jj_la1[15] = jj_gen;
      ;
    }
                if (args == null) {
                        args = ASTFactory.createLiteralTextNodeList();
                }
                if (arg != null)
                        args.add(0, arg);
                {if (true) return args;}
    throw new Error("Missing return statement in function");
  }

//////
  final public IASTListNode<IASTLiteralTextNode> ArgumentsAndNewlines() throws ParseException {
        IASTListNode<IASTLiteralTextNode> args = null;
    args = ArgumentAndNewlineList();
                if (args != null)
                        ParserUtils.setSourceRangeForListNode(null, args, null);
                {if (true) return args;}
    throw new Error("Missing return statement in function");
  }

  final public IASTListNode<IASTLiteralTextNode> ArgumentAndNewlineList() throws ParseException {
        IASTLiteralTextNode arg = null;
        IASTListNode<IASTLiteralTextNode> args = null;
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case EOL:
    case ARGUMENT:
      arg = ArgumentOrNewline();
      args = ArgumentAndNewlineList();
                if (arg != null) {
                        if (args == null)
                                args = ASTFactory.createLiteralTextNodeList();
                        args.add(0, arg);
                }
                {if (true) return args;}
      break;
    default:
      jj_la1[16] = jj_gen;
        {if (true) return null;}
    }
    throw new Error("Missing return statement in function");
  }

  final public IASTLiteralTextNode ArgumentOrNewline() throws ParseException {
        IASTLiteralTextNode arg = null;
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case ARGUMENT:
      arg = Argument();
                {if (true) return arg;}
      break;
    case EOL:
      jj_consume_token(EOL);
                {if (true) return null;}
      break;
    default:
      jj_la1[17] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
    throw new Error("Missing return statement in function");
  }

/**
 *	Empty line.
 */
  final public IASTBldInfStatement Empty() throws ParseException {
    jj_consume_token(EOL);
                {if (true) return null;}
    throw new Error("Missing return statement in function");
  }

  final public IASTLiteralTextNode ppRestOfLine(boolean skip) throws ParseException {
        Token start = token, end = start;
        if (skip)
                start = end = getNextToken();
        while (true) {
                end = getNextToken();
                if (end.kind == EOL || end.kind == EOF)
                        break;
        }
                {if (true) return getLiteralTextNodeSpanningUpTo(start, end);}
    throw new Error("Missing return statement in function");
  }

  public TokenManager token_source;
  public Token token, jj_nt;
  private int jj_ntk;
  private int jj_gen;
  final private int[] jj_la1 = new int[18];
  static private int[] jj_la1_0;
  static {
      jj_la1_0();
   }
   private static void jj_la1_0() {
      jj_la1_0 = new int[] {0xd8d0,0xd8fe,0x20,0xc0,0x40720,0x700,0x1800,0x2000,0x42020,0xc000,0x10020,0x4002e,0xe,0x4002e,0x40000,0x40000,0x40020,0x40020,};
   }


  public BldInfParserCore(TokenManager tm) {
    token_source = tm;
    token = new Token();
    jj_ntk = -1;
    jj_gen = 0;
    for (int i = 0; i < 18; i++) jj_la1[i] = -1;
  }

  public void ReInit(TokenManager tm) {
    token_source = tm;
    token = new Token();
    jj_ntk = -1;
    jj_gen = 0;
    for (int i = 0; i < 18; i++) jj_la1[i] = -1;
  }

  final private Token jj_consume_token(int kind) throws ParseException {
    Token oldToken;
    if ((oldToken = token).next != null) token = token.next;
    else token = token.next = token_source.getNextToken();
    jj_ntk = -1;
    if (token.kind == kind) {
      jj_gen++;
      return token;
    }
    token = oldToken;
    jj_kind = kind;
    throw generateParseException();
  }

  final public Token getNextToken() {
    if (token.next != null) token = token.next;
    else token = token.next = token_source.getNextToken();
    jj_ntk = -1;
    jj_gen++;
    return token;
  }

  final public Token getToken(int index) {
    Token t = token;
    for (int i = 0; i < index; i++) {
      if (t.next != null) t = t.next;
      else t = t.next = token_source.getNextToken();
    }
    return t;
  }

  final private int jj_ntk() {
    if ((jj_nt=token.next) == null)
      return (jj_ntk = (token.next=token_source.getNextToken()).kind);
    else
      return (jj_ntk = jj_nt.kind);
  }

  private java.util.Vector jj_expentries = new java.util.Vector();
  private int[] jj_expentry;
  private int jj_kind = -1;

  public ParseException generateParseException() {
    jj_expentries.removeAllElements();
    boolean[] la1tokens = new boolean[19];
    for (int i = 0; i < 19; i++) {
      la1tokens[i] = false;
    }
    if (jj_kind >= 0) {
      la1tokens[jj_kind] = true;
      jj_kind = -1;
    }
    for (int i = 0; i < 18; i++) {
      if (jj_la1[i] == jj_gen) {
        for (int j = 0; j < 32; j++) {
          if ((jj_la1_0[i] & (1<<j)) != 0) {
            la1tokens[j] = true;
          }
        }
      }
    }
    for (int i = 0; i < 19; i++) {
      if (la1tokens[i]) {
        jj_expentry = new int[1];
        jj_expentry[0] = i;
        jj_expentries.addElement(jj_expentry);
      }
    }
    int[][] exptokseq = new int[jj_expentries.size()][];
    for (int i = 0; i < jj_expentries.size(); i++) {
      exptokseq[i] = (int[])jj_expentries.elementAt(i);
    }
    return new ParseException(token, exptokseq, tokenImage);
  }

  final public void enable_tracing() {
  }

  final public void disable_tracing() {
  }

}
