# Path: progSpec.py
# def cdlog(lvl, mesg):
#     global MaxLogLevelToShow
#     global lastLogMesgs
#     global highestLvl
#     highestLvl=lvl
#     resizeLogArray(lvl)
#     lastLogMesgs[lvl]=mesg
#     for i in range(highestLvl+1, len(lastLogMesgs)):
#         lastLogMesgs[i]=''
#     if(lvl<=MaxLogLevelToShow):
#         if(lvl==0): print('')
#         printAtLvl(lvl, mesg, '|    ')
# 
# def cdErr(mesg):
#     global lastLogMesgs
#     global highestLvl
#     highestLvl+=1
#     lastLogMesgs[highestLvl]="\n\nError: "+mesg
#     exit(1)
# 
# def logLvl():
#     return highestLvl+1


import re
import progSpec
from progSpec import cdlog, cdErr, logLvl
from pyparsing import *
        | (Literal("::")('deprecateDoubleColon') + CID("fieldName") + Group(parameters)("parameters"))# deprecated
        | (Literal("::")('allocDoubleColon') + CID("fieldName"))
    )("nameAndVal")
datastructID = Group(Keyword("list") | Keyword("opt") | Keyword("map") | Keyword("multimap") | Keyword("tree") | Keyword("graph") | Keyword("iterableList"))('datastructID')
arraySpec = Group('[' + Optional(owners)('owner') + datastructID + Optional(Group(intNum | Optional(Group(owners)('IDXowner')) + varType('idxBaseType'))('indexType')) + ']')("arraySpec")
meOrMy = Keyword("me") | Keyword("my")
modeSpec = Optional(meOrMy)('owner') + Keyword("mode")("modeIndicator") - "[" - CIDList("modeList") + "]" + nameAndVal
altModeSpec = Keyword("mode")("altModeIndicator") - "[" - Group(delimitedList(CID, ','))("altModeList") + "]"
flagDef  = Optional(meOrMy)('owner') + Keyword("flag")("flagIndicator") - nameAndVal
baseType = cppType | numRange

#########################################   O B J E C T   D E S C R I P T I O N S
fieldDefs = ZeroOrMore(fieldDef)("fieldDefs")
SetFieldStmt = Group(Word(alphanums + "_.") + '=' + Word(alphanums + r"_. */+-(){}[]\|<>,./?`~@#$%^&*=:!'" + '"'))
coFactualEl  = Group("(" + Group(fieldDef + "<=>" + Group(OneOrMore(SetFieldStmt + Suppress(';'))))  + ")")("coFactualEl")
sequenceEl = "{" - fieldDefs + "}"
alternateEl  = "[" - Group(OneOrMore((coFactualEl | fieldDef) + Optional("|").suppress()))("fieldDefs") + "]"
anonModel = sequenceEl("sequenceEl") | alternateEl("alternateEl")
owners <<= Keyword("const") | Keyword("me") | Keyword("my") | Keyword("our") | Keyword("their") | Keyword("we") | Keyword("itr") | Keyword("id_our") | Keyword("id_their")
fullFieldDef <<= Optional('>')('isNext') + Optional(owners)('owner') + Group(baseType | altModeSpec | classSpec | Group(anonModel) | datastructID)('fieldType') + Optional(arraySpec) + Optional(nameAndVal)
fieldDef <<= Group(flagDef('flagDef') | modeSpec('modeDef') | (quotedString('constStr') + Optional("[opt]") + Optional(":"+CID)) | intNum('constNum') | nameAndVal('nameVal') | fullFieldDef('fullFieldDef'))("fieldDef")
modelTypes = (Keyword("model") | Keyword("struct") | Keyword("string") | Keyword("stream"))
objectDef = Group(modelTypes + classDef + Optional(Literal(":")("optionalTag") + tagDefList) + (Keyword('auto') | anonModel))("objectDef")
doPattern = Group(Keyword("do") + classSpec + Suppress("(") + CIDList + Suppress(")"))("doPattern")
macroDef  = Group(Keyword("#define") + CID('macroName') + Suppress("(") + Optional(CIDList('macroArgs')) + Suppress(")") + Group("<%" + SkipTo("%>", include=True))("macroBody"))
objectList = Group(ZeroOrMore(objectDef | doPattern | macroDef))("objectList")
objectDef.setParseAction(logObj)
fieldDef.setParseAction(logFieldDef)

#########################################   P A R S E R   S T A R T   S Y M B O L

# Path: progSpec.py
# def cdlog(lvl, mesg):
#     global MaxLogLevelToShow
#     global lastLogMesgs
#     global highestLvl
#     highestLvl=lvl
#     resizeLogArray(lvl)
#     lastLogMesgs[lvl]=mesg
#     for i in range(highestLvl+1, len(lastLogMesgs)):
#         lastLogMesgs[i]=''
#     if(lvl<=MaxLogLevelToShow):
#         if(lvl==0): print('')
#         printAtLvl(lvl, mesg, '|    ')
# 
# def cdErr(mesg):
#     global lastLogMesgs
#     global highestLvl
#     highestLvl+=1
#     lastLogMesgs[highestLvl]="\n\nError: "+mesg
#     exit(1)
# 
# def logLvl():
#     return highestLvl+1


# Path: codeDogParser.py
import re
import progSpec
from progSpec import cdlog, cdErr, logLvl
from pyparsing import *

        | (Literal("::")('deprecateDoubleColon') + CID("fieldName") + Group(parameters)("parameters"))# deprecated
        | (Literal("::")('allocDoubleColon') + CID("fieldName"))
    )("nameAndVal")
datastructID = Group(Keyword("list") | Keyword("opt") | Keyword("map") | Keyword("multimap") | Keyword("tree") | Keyword("graph") | Keyword("iterableList"))('datastructID')
arraySpec = Group('[' + Optional(owners)('owner') + datastructID + Optional(Group(intNum | Optional(Group(owners)('IDXowner')) + varType('idxBaseType'))('indexType')) + ']')("arraySpec")
meOrMy = Keyword("me") | Keyword("my")
modeSpec = Optional(meOrMy)('owner') + Keyword("mode")("modeIndicator") - "[" - CIDList("modeList") + "]" + nameAndVal
altModeSpec = Keyword("mode")("altModeIndicator") - "[" - Group(delimitedList(CID, ','))("altModeList") + "]"
flagDef  = Optional(meOrMy)('owner') + Keyword("flag")("flagIndicator") - nameAndVal
baseType = cppType | numRange

#########################################   O B J E C T   D E S C R I P T I O N S
fieldDefs = ZeroOrMore(fieldDef)("fieldDefs")
SetFieldStmt = Group(Word(alphanums + "_.") + '=' + Word(alphanums + r"_. */+-(){}[]\|<>,./?`~@#$%^&*=:!'" + '"'))
coFactualEl  = Group("(" + Group(fieldDef + "<=>" + Group(OneOrMore(SetFieldStmt + Suppress(';'))))  + ")")("coFactualEl")
sequenceEl = "{" - fieldDefs + "}"
alternateEl  = "[" - Group(OneOrMore((coFactualEl | fieldDef) + Optional("|").suppress()))("fieldDefs") + "]"
anonModel = sequenceEl("sequenceEl") | alternateEl("alternateEl")
owners <<= Keyword("const") | Keyword("me") | Keyword("my") | Keyword("our") | Keyword("their") | Keyword("we") | Keyword("itr") | Keyword("id_our") | Keyword("id_their")
fullFieldDef <<= Optional('>')('isNext') + Optional(owners)('owner') + Group(baseType | altModeSpec | classSpec | Group(anonModel) | datastructID)('fieldType') + Optional(arraySpec) + Optional(nameAndVal)
fieldDef <<= Group(flagDef('flagDef') | modeSpec('modeDef') | (quotedString('constStr') + Optional("[opt]") + Optional(":"+CID)) | intNum('constNum') | nameAndVal('nameVal') | fullFieldDef('fullFieldDef'))("fieldDef")
modelTypes = (Keyword("model") | Keyword("struct") | Keyword("string") | Keyword("stream"))
objectDef = Group(modelTypes + classDef + Optional(Literal(":")("optionalTag") + tagDefList) + (Keyword('auto') | anonModel))("objectDef")
doPattern = Group(Keyword("do") + classSpec + Suppress("(") + CIDList + Suppress(")"))("doPattern")
macroDef  = Group(Keyword("#define") + CID('macroName') + Suppress("(") + Optional(CIDList('macroArgs')) + Suppress(")") + Group("<%" + SkipTo("%>", include=True))("macroBody"))
objectList = Group(ZeroOrMore(objectDef | doPattern | macroDef))("objectList")
objectDef.setParseAction(logObj)
fieldDef.setParseAction(logFieldDef)

#########################################   P A R S E R   S T A R T   S Y M B O L

progSpecParser = Group(Optional(buildSpecList.setParseAction(logBSL)) + tagDefList.setParseAction(logTags) + objectList)("progSpecParser")