import Oql


try:
    import os, gettext
    locale_dir = os.path.split(__file__)[0]
    gettext.install('4Suite', locale_dir)
except (ImportError, AttributeError, IOError):
    def _(msg):
        return msg

SYNTAX_ERR_MSG = _("Error parsing query:\n'%s'\nSyntax error at or near '%s' Line: %d, Production Number: %s")
INTERNAL_ERR_MSG = _("Error parsing query:\n'%s'\nInternal error in processing at or near '%s', Line: %d, Production Number: %s, Exception: %s")

class SyntaxException(Exception):
    def __init__(self, source, lineNum, location, prodNum):
        Exception.__init__(self, SYNTAX_ERR_MSG%(source, location, lineNum, prodNum))
        self.source = source
        self.lineNum = lineNum
        self.loc = location
        self.prodNum = prodNum

class InternalException(Exception):
    def __init__(self, source, lineNum, location, prodNum, exc, val, tb):
        Exception.__init__(self, INTERNAL_ERR_MSG%(source, location, lineNum, prodNum, exc))
        self.source = source
        self.lineNum = lineNum
        self.loc = location
        self.prodNum = prodNum
        self.errorType = exc
        self.errorValue = val
        self.errorTraceback = tb

class OqlParserBase:
    def __init__(self):
        self.initialize()

    def initialize(self):
        self.results = None
        self.__stack = []
        Oql.cvar.g_prodNum = "-1"
        Oql.cvar.g_errorOccured = 0

    def parse(self,st):
        self.initialize()
        Oql.my_Oqlparse(self,st)
        if Oql.cvar.g_errorOccured == 1:
            raise SyntaxException(
                st,
                Oql.cvar.lineNum,
                Oql.cvar.g_errorLocation,
                Oql.cvar.g_prodNum)
        if Oql.cvar.g_errorOccured == 2:
            raise InternalException(
                st,
                Oql.cvar.lineNum,
                Oql.cvar.g_errorLocation,
                Oql.cvar.g_prodNum,
                Oql.cvar.g_errorType,
                Oql.cvar.g_errorValue,
                Oql.cvar.g_errorTraceback)
        return self.__stack

    def pop(self):
        if len(self.__stack):
            rt = self.__stack[-1]
            del self.__stack[-1]
            return rt
        self.raiseException("Pop with 0 stack length")

    def push(self,item):
        self.__stack.append(item)

    def empty(self):
        return len(self.__stack) == 0

    def size(self):
        return len(self.__stack)

    def raiseException(self, message):
        raise Exception(message + "\n" +
                        "EBNF ProductionNumber: " +
                        str(Oql.cvar.g_prodNum)
                        )

    ### Callback methods ###

    def queryProgram(self, arg0 = None, arg1 = None, arg2 = None):
        print 'queryProgram called with %s %s %s ' % (str(arg0), str(arg1), str(arg2))
    def declarationList(self, arg0 = None, arg1 = None, arg2 = None):
        print 'declarationList called with %s %s %s ' % (str(arg0), str(arg1), str(arg2))
    def queryList(self, arg0 = None, arg1 = None, arg2 = None):
        print 'queryList called with %s %s %s ' % (str(arg0), str(arg1), str(arg2))
    def declaration(self, arg0 = None):
        print 'declaration called with %s ' % (str(arg0))
    def oql_import(self, arg0 = None, arg1 = None, arg2 = None, arg3 = None):
        print 'oql_import called with %s %s %s %s ' % (str(arg0), str(arg1), str(arg2), str(arg3))
    def defineQuery(self, arg0 = None, arg1 = None, arg2 = None, arg3 = None, arg4 = None, arg5 = None, arg6 = None, arg7 = None):
        print 'defineQuery called with %s %s %s %s %s %s %s %s ' % (str(arg0), str(arg1), str(arg2), str(arg3), str(arg4), str(arg5), str(arg6), str(arg7))
    def parameterList(self, arg0 = None, arg1 = None, arg2 = None, arg3 = None):
        print 'parameterList called with %s %s %s %s ' % (str(arg0), str(arg1), str(arg2), str(arg3))
    def undefineQuery(self, arg0 = None, arg1 = None, arg2 = None):
        print 'undefineQuery called with %s %s %s ' % (str(arg0), str(arg1), str(arg2))
    def qualifiedName(self, arg0 = None, arg1 = None, arg2 = None):
        print 'qualifiedName called with %s %s %s ' % (str(arg0), str(arg1), str(arg2))
    def query(self, arg0 = None):
        print 'query called with %s ' % (str(arg0))
    def selectExpr(self, arg0 = None, arg1 = None, arg2 = None, arg3 = None, arg4 = None, arg5 = None, arg6 = None):
        print 'selectExpr called with %s %s %s %s %s %s %s ' % (str(arg0), str(arg1), str(arg2), str(arg3), str(arg4), str(arg5), str(arg6))
    def projectionAttributes(self, arg0 = None):
        print 'projectionAttributes called with %s ' % (str(arg0))
    def projectionList(self, arg0 = None, arg1 = None, arg2 = None):
        print 'projectionList called with %s %s %s ' % (str(arg0), str(arg1), str(arg2))
    def projection(self, arg0 = None, arg1 = None, arg2 = None):
        print 'projection called with %s %s %s ' % (str(arg0), str(arg1), str(arg2))
    def fromClause(self, arg0 = None, arg1 = None):
        print 'fromClause called with %s %s ' % (str(arg0), str(arg1))
    def iteratorDefList(self, arg0 = None, arg1 = None, arg2 = None):
        print 'iteratorDefList called with %s %s %s ' % (str(arg0), str(arg1), str(arg2))
    def iteratorDef(self, arg0 = None, arg1 = None, arg2 = None):
        print 'iteratorDef called with %s %s %s ' % (str(arg0), str(arg1), str(arg2))
    def whereClause(self, arg0 = None, arg1 = None):
        print 'whereClause called with %s %s ' % (str(arg0), str(arg1))
    def groupClause(self, arg0 = None, arg1 = None, arg2 = None):
        print 'groupClause called with %s %s %s ' % (str(arg0), str(arg1), str(arg2))
    def havingClauseList(self, arg0 = None, arg1 = None):
        print 'havingClauseList called with %s %s ' % (str(arg0), str(arg1))
    def havingClause(self, arg0 = None, arg1 = None):
        print 'havingClause called with %s %s ' % (str(arg0), str(arg1))
    def orderClause(self, arg0 = None, arg1 = None):
        print 'orderClause called with %s %s ' % (str(arg0), str(arg1))
    def sortCriterionList(self, arg0 = None, arg1 = None, arg2 = None):
        print 'sortCriterionList called with %s %s %s ' % (str(arg0), str(arg1), str(arg2))
    def sortCriterion(self, arg0 = None, arg1 = None):
        print 'sortCriterion called with %s %s ' % (str(arg0), str(arg1))
    def expr(self, arg0 = None):
        print 'expr called with %s ' % (str(arg0))
    def castExpr(self, arg0 = None, arg1 = None, arg2 = None, arg3 = None):
        print 'castExpr called with %s %s %s %s ' % (str(arg0), str(arg1), str(arg2), str(arg3))
    def orExpr(self, arg0 = None, arg1 = None):
        print 'orExpr called with %s %s ' % (str(arg0), str(arg1))
    def orelseExpr(self, arg0 = None, arg1 = None, arg2 = None):
        print 'orelseExpr called with %s %s %s ' % (str(arg0), str(arg1), str(arg2))
    def andExpr(self, arg0 = None, arg1 = None, arg2 = None):
        print 'andExpr called with %s %s %s ' % (str(arg0), str(arg1), str(arg2))
    def quantifierExpr(self, arg0 = None, arg1 = None, arg2 = None, arg3 = None):
        print 'quantifierExpr called with %s %s %s %s ' % (str(arg0), str(arg1), str(arg2), str(arg3))
    def inClause(self, arg0 = None, arg1 = None, arg2 = None):
        print 'inClause called with %s %s %s ' % (str(arg0), str(arg1), str(arg2))
    def andthenExpr(self, arg0 = None, arg1 = None):
        print 'andthenExpr called with %s %s ' % (str(arg0), str(arg1))
    def equalityExpr(self, arg0 = None, arg1 = None, arg2 = None, arg3 = None):
        print 'equalityExpr called with %s %s %s %s ' % (str(arg0), str(arg1), str(arg2), str(arg3))
    def relationalExpr(self, arg0 = None, arg1 = None, arg2 = None):
        print 'relationalExpr called with %s %s %s ' % (str(arg0), str(arg1), str(arg2))
    def relationalOperand(self, arg0 = None):
        print 'relationalOperand called with %s ' % (str(arg0))
    def compositePredicate(self, arg0 = None):
        print 'compositePredicate called with %s ' % (str(arg0))
    def additiveExpr(self, arg0 = None, arg1 = None, arg2 = None):
        print 'additiveExpr called with %s %s %s ' % (str(arg0), str(arg1), str(arg2))
    def additiveOperand(self, arg0 = None):
        print 'additiveOperand called with %s ' % (str(arg0))
    def multiplicativeExpr(self, arg0 = None, arg1 = None, arg2 = None):
        print 'multiplicativeExpr called with %s %s %s ' % (str(arg0), str(arg1), str(arg2))
    def multiplicativeOperand(self, arg0 = None):
        print 'multiplicativeOperand called with %s ' % (str(arg0))
    def inExpr(self, arg0 = None, arg1 = None):
        print 'inExpr called with %s %s ' % (str(arg0), str(arg1))
    def unaryExpr(self, arg0 = None, arg1 = None):
        print 'unaryExpr called with %s %s ' % (str(arg0), str(arg1))
    def unaryOperand(self, arg0 = None):
        print 'unaryOperand called with %s ' % (str(arg0))
    def postfixExpr(self, arg0 = None, arg1 = None, arg2 = None, arg3 = None):
        print 'postfixExpr called with %s %s %s %s ' % (str(arg0), str(arg1), str(arg2), str(arg3))
    def postfixOperandList(self, arg0 = None, arg1 = None):
        print 'postfixOperandList called with %s %s ' % (str(arg0), str(arg1))
    def postfixOperand(self, arg0 = None, arg1 = None, arg2 = None):
        print 'postfixOperand called with %s %s %s ' % (str(arg0), str(arg1), str(arg2))
    def index(self, arg0 = None, arg1 = None, arg2 = None):
        print 'index called with %s %s %s ' % (str(arg0), str(arg1), str(arg2))
    def exprList(self, arg0 = None, arg1 = None, arg2 = None):
        print 'exprList called with %s %s %s ' % (str(arg0), str(arg1), str(arg2))
    def argList(self, arg0 = None, arg1 = None, arg2 = None):
        print 'argList called with %s %s %s ' % (str(arg0), str(arg1), str(arg2))
    def primaryExpr(self, arg0 = None, arg1 = None, arg2 = None):
        print 'primaryExpr called with %s %s %s ' % (str(arg0), str(arg1), str(arg2))
    def conversionExpr(self, arg0 = None, arg1 = None, arg2 = None, arg3 = None):
        print 'conversionExpr called with %s %s %s %s ' % (str(arg0), str(arg1), str(arg2), str(arg3))
    def collectionExpr(self, arg0 = None, arg1 = None, arg2 = None, arg3 = None):
        print 'collectionExpr called with %s %s %s %s ' % (str(arg0), str(arg1), str(arg2), str(arg3))
    def aggregateExpr(self, arg0 = None, arg1 = None, arg2 = None, arg3 = None):
        print 'aggregateExpr called with %s %s %s %s ' % (str(arg0), str(arg1), str(arg2), str(arg3))
    def undefinedExpr(self, arg0 = None, arg1 = None, arg2 = None, arg3 = None):
        print 'undefinedExpr called with %s %s %s %s ' % (str(arg0), str(arg1), str(arg2), str(arg3))
    def objectConstruction(self, arg0 = None, arg1 = None, arg2 = None, arg3 = None):
        print 'objectConstruction called with %s %s %s %s ' % (str(arg0), str(arg1), str(arg2), str(arg3))
    def structConstruction(self, arg0 = None, arg1 = None, arg2 = None, arg3 = None):
        print 'structConstruction called with %s %s %s %s ' % (str(arg0), str(arg1), str(arg2), str(arg3))
    def fieldList(self, arg0 = None, arg1 = None, arg2 = None):
        print 'fieldList called with %s %s %s ' % (str(arg0), str(arg1), str(arg2))
    def field(self, arg0 = None, arg1 = None, arg2 = None):
        print 'field called with %s %s %s ' % (str(arg0), str(arg1), str(arg2))
    def collectionConstruction(self, arg0 = None, arg1 = None, arg2 = None, arg3 = None):
        print 'collectionConstruction called with %s %s %s %s ' % (str(arg0), str(arg1), str(arg2), str(arg3))
    def valueList(self, arg0 = None, arg1 = None, arg2 = None):
        print 'valueList called with %s %s %s ' % (str(arg0), str(arg1), str(arg2))
    def listRange(self, arg0 = None, arg1 = None, arg2 = None):
        print 'listRange called with %s %s %s ' % (str(arg0), str(arg1), str(arg2))
    def queryParam(self, arg0 = None, arg1 = None):
        print 'queryParam called with %s %s ' % (str(arg0), str(arg1))
    def type(self, arg0 = None, arg1 = None, arg2 = None, arg3 = None, arg4 = None, arg5 = None):
        print 'type called with %s %s %s %s %s %s ' % (str(arg0), str(arg1), str(arg2), str(arg3), str(arg4), str(arg5))
    def literal(self, arg0 = None):
        print 'literal called with %s ' % (str(arg0))
    def booleanLiteral(self, arg0 = None):
        print 'booleanLiteral called with %s ' % (str(arg0))
    def longLiteral(self, arg0 = None):
        print 'longLiteral called with %s ' % (str(arg0))
    def doubleLiteral(self, arg0 = None):
        print 'doubleLiteral called with %s ' % (str(arg0))
    def charLiteral(self, arg0 = None):
        print 'charLiteral called with %s ' % (str(arg0))
    def stringLiteral(self, arg0 = None):
        print 'stringLiteral called with %s ' % (str(arg0))
    def dateLiteral(self, arg0 = None, arg1 = None, arg2 = None, arg3 = None, arg4 = None, arg5 = None, arg6 = None, arg7 = None):
        print 'dateLiteral called with %s %s %s %s %s %s %s %s ' % (str(arg0), str(arg1), str(arg2), str(arg3), str(arg4), str(arg5), str(arg6), str(arg7))
    def timeLiteral(self, arg0 = None, arg1 = None, arg2 = None, arg3 = None, arg4 = None, arg5 = None, arg6 = None, arg7 = None):
        print 'timeLiteral called with %s %s %s %s %s %s %s %s ' % (str(arg0), str(arg1), str(arg2), str(arg3), str(arg4), str(arg5), str(arg6), str(arg7))
    def timestampLiteral(self, arg0 = None, arg1 = None, arg2 = None, arg3 = None, arg4 = None, arg5 = None, arg6 = None, arg7 = None, arg8 = None, arg9 = None, arg10 = None, arg11 = None, arg12 = None):
        print 'timestampLiteral called with %s %s %s %s %s %s %s %s %s %s %s %s %s ' % (str(arg0), str(arg1), str(arg2), str(arg3), str(arg4), str(arg5), str(arg6), str(arg7), str(arg8), str(arg9), str(arg10), str(arg11), str(arg12))
def PrintSyntaxException(e):
    print "********** Syntax Exception **********"
    print "Exception at or near '%s'" % e.loc
    print "  Line: %d, Production Number: %s" % (e.lineNum, str(e.prodNum))

def PrintInternalException(e):
    print "********** Internal Exception **********"
    print "Exception at or near '%s'" % e.loc
    print "  Line: %d, Production Number: %s" % (e.lineNum, e.prodNum)
    print "    Exception: %s" % e.errorType
    print "Original traceback:"
    import traceback
    traceback.print_tb(e.errorTraceback)

if __name__ == "__main__":
    import sys
    p = OqlParserBase()
    if len(sys.argv) == 2:
        l = open(sys.argv[1],"r").read()
    else:
        l = raw_input(">>>")
    try:
        p.parse(l)
    except InternalException, e:
        PrintInternalException(e)
    except SyntaxException, e:
        PrintSyntaxException(e)
