from pyparsing import *
ALPHA = alphas
DIGIT = nums
HEXDIG = "0123456789ABCDEF"
SafeChar = alphanums +  "+-&!_'?@^`~*$\\()%+."
RestChar = ";[]{}:,#<>="
COLON = ":"
DOT = "."
SLASH = "/"
DQUOTE = '"'
SP = " "
HTAB = '\\0x09'
HTAB = ''
EOL = Suppress(lineEnd)
WSP = SP + HTAB 
COMMENT = Word(";",  SafeChar + RestChar + WSP + '"') + EOL
LWSP = Suppress(Word(WSP))
nonEscapeChar = "}" + srange("[\\0x01-\\0x7c]") #+ srange("[\\0x7E-\\0xFF]")
nonEscapeChar = srange("[\\0x01-\\0x7c]") #+ srange("[\\0x7E-\\0xFF]")
octetString = Word(nonEscapeChar)
quotedString = dblQuotedString
UINT16 = Word(DIGIT, min=1, max=5) 
UINT32 = Word(DIGIT, min=1, max=10) 
NAME = Word(ALPHA, alphanums + "_", min=1, max=64)
VALUE = quotedString | Word(SafeChar) #| srange("[\\0x80-\\0xFF]")
EQUAL = Suppress("=")
LBRKT = Suppress( "{" )
RBRKT = Suppress( "}" )
COMMA = Suppress(",")
SEP = ((WSP | EOL | COMMENT) + LWSP)
#### TOKEN
AddToken = Literal("Add") | Literal("A")
AndAUDITselectToken = Literal("ANDLgc")
AuditToken = Literal("Audit") | Literal("AT")
AuditCapToken = Literal("AuditCapability") |  Literal("AC")
AuditValueToken = Literal("AuditValue") | Literal("AV")
AuthToken = Literal("Authentication") | Literal("AU")
BothwayToken = Literal("Bothway") | Literal("BW")
BothToken = Literal("Both") | Literal("B")
BriefToken = Literal("Brief") | Literal("BR")
BufferToken = Literal("Buffer") | Literal("BF")
CtxToken = Literal("Context") | Literal("C")
ContextAttrToken = Literal("ContextAttr") | Literal("CT") 
ContextListToken = Literal("ContextList") | Literal("CLT")
ContextAuditToken = Literal("ContextAudit") | Literal("CA")
DigitMapToken = Literal("DigitMap") | Literal("DM")
DirectionToken = Literal("SPADirection") | Literal("SPADI")
DisconnectedToken = Literal("Disconnected") | Literal("DC")
DelayToken = Literal("Delay") | Literal("DL")
DurationToken = Literal("Duration") | Literal("DR")
EmbedToken = Literal("Embed") | Literal("EM")
EmergencyToken = Literal("Emergency") | Literal("EG")
EmergencyOffToken = Literal("EmergencyOff") | Literal("EGO")
EmergencyValueToken  = Literal("EmergencyValue") | Literal("EGV") 
ErrorToken = Literal("Error") | Literal("ER")
EventBufferToken = Literal("EventBuffer") | Literal("EB")
EventsToken = Literal("Events") | Literal("E")
ExternalToken = Literal("External") | Literal("EX")
FailoverToken = Literal("Failover") | Literal("FL")
ForcedToken = Literal("Forced") | Literal("FO")
GracefulToken = Literal("Graceful") | Literal("GR")
H221Token = Literal("H221")
H223Token = Literal("H223")
H226Token = Literal("H226")
HandOffToken = Literal("HandOff") | Literal("HO")
IEPSToken = Literal("IEPSCall") | Literal("IEPS")
ImmAckRequiredToken = Literal("ImmAckRequired") | Literal("IA")
InactiveToken = Literal("Inactive") | Literal("IN")
InternalToken = Literal("Internal") | Literal("IT") 
IntsigDelayToken = Literal("Intersignal") | Literal("SPAIS") 
IsolateToken = Literal("Isolate") | Literal("IS")
InSvcToken = Literal("InService") | Literal("IV")
InterruptByEventToken = Literal("IntByEvent") | Literal("IBE")
InterruptByNewSignalsDescrToken = Literal("IntBySigDescr") | Literal("IBS")
IterationToken = Literal("Iteration") | Literal("IR")
KeepActiveToken = Literal("KeepActive") | Literal("KA")
LocalToken = Literal("Local") | Literal("L")
LocalControlToken = Literal("LocalControl") | Literal("O")
LockStepToken = Literal("LockStep") | Literal("SP")
LoopbackToken = Literal("Loopback") | Literal("LB")
MediaToken = Literal("Media") | Literal("M")
MegacopToken = Literal("MEGACO") | Literal("!")
MessageSegmentToken = Literal("Segment") | Literal("SM")
MethodToken = Literal("Method") | Literal("MT")
MgcIdToken = Literal("MgcIdToTry") | Literal("MG")
ModeToken = Literal("Mode") | Literal("MO")
ModifyToken = Literal("Modify") | Literal("MF")
ModemToken = Literal("Modem") | Literal("MD")
MoveToken = Literal("Move") | Literal("MV")
MTPToken = Literal("MTP")
MuxToken = Literal("Mux") | Literal("MX")
NotifyToken = Literal("Notify") | Literal("N")
NotifyCompletionToken = Literal("NotifyCompletion") | Literal("NC")
ObservedEventsToken   = Literal("ObservedEvents") | Literal("OE")
OnewayToken           = Literal("Oneway") | Literal("OW")
OnewayBothToken   = Literal("OnewayBoth") | Literal("OWB") 
OnewayExternalToken  = Literal("OnewayExternal") | Literal("OWE")
OnOffToken            = Literal("OnOff") | Literal("OO")
OrAUDITselectToken = Literal("ORLgc")
OtherReasonToken      = Literal("OtherReason") | Literal("OR")
OutOfSvcToken         = Literal("OutOfService") | Literal("OS")
PackagesToken         = Literal("Packages") | Literal("PG")
PendingToken = Literal("Pending") | Literal("PN")
PriorityToken = Literal("Priority") | Literal("PR")
ProfileToken = Literal("Profile") | Literal("PF")
ReasonToken = Literal("Reason") | Literal("RE")
RecvonlyToken = Literal("ReceiveOnly") | Literal("RC")
ReplyToken = Literal("Reply") | Literal("P")
RestartToken = Literal("Restart") | Literal("RS")
RemoteToken = Literal("Remote") | Literal("R")
RequestIDToken = Literal("SPARequestID") | Literal("SPARQ")
ReservedGroupToken = Literal("ReservedGroup") | Literal("RG")
ReservedValueToken = Literal("ReservedValue") | Literal("RV")
SegmentationCompleteToken = Literal("END") | Literal("&")
SendonlyToken = Literal("SendOnly") | Literal("SO")
SendrecvToken = Literal("SendReceive") | Literal("SR")
ServicesToken = Literal("Services") | Literal("SV")
ServiceStatesToken = Literal("ServiceStates") | Literal("SI")
ServiceChangeIncompleteToken = Literal("ServiceChangeInc") | Literal("SIC")
ServiceChangeToken = Literal("ServiceChange") | Literal("SC")
ServiceChangeAddressToken = Literal("ServiceChangeAddress") | Literal("AD")
SignalListToken = Literal("SignalList") | Literal("SL")
SignalsToken = Literal("Signals") | Literal("SG")
SignalTypeToken = Literal("SignalType") | Literal("SY")
StatsToken = Literal("Statistics") | Literal("SA")
StreamToken = Literal("Stream") | Literal("ST")
SubtractToken = Literal("Subtract") | Literal("S")
SynchISDNToken = Literal("SynchISDN") | Literal("SN")
TerminationStateToken = Literal("TerminationState") | Literal("TS")
TestToken = Literal("Test") | Literal("TE")
TimeOutToken = Literal("TimeOut") | Literal("TO")
TopologyToken = Literal("Topology") | Literal("TP")
TransToken = Literal("Transaction") | Literal("T")
ResponseAckToken = Literal("TransactionResponseAck") |  Literal("K")
V18Token = Literal("V18")
V22Token = Literal("V22")
V22bisToken = Literal("V22b")
V32Token = Literal("V32")
V32bisToken = Literal("V32b")
V34Token = Literal("V34")
V76Token = Literal("V76")
V90Token = Literal("V90")
V91Token = Literal("V91")
VersionToken = Literal("Version") | Literal("V")

### END TOKEN
RSBRKT=Suppress("]")
LSBRKT=Suppress("]")
INEQUAL=Suppress(LWSP+(Literal(">")|"<"|"#")+LWSP)("INEQUAL")
ContextID=Combine((UINT32|"*"|"-"|"$"))("ContextID")
ItemID=NAME("ItemID")
PackageName=NAME("PackageName")
StreamID=UINT16("StreamID")
Time=(Word(DIGIT, exact=8))("Time")
Date=(Word(DIGIT, exact=8))("Date")
RequestID=(UINT32|"*")("RequestID")
digitMapName=NAME("digitMapName")
sigParameterName=NAME("sigParameterName")
signalListId=UINT16("signalListId")
pathDomainName=Group(Word(alphanums+"*",alphanums+"-"+"*"+".",max=64))("pathDomainName")
pathNAME=Combine(Optional("*")+NAME+Word("/"+"*"+alphanums+"_"+"$")+Optional("@"+pathDomainName))("pathNAME")
pkgdName=Combine((PackageName+SLASH+ItemID)|(PackageName+SLASH+"*")|("*"+SLASH+"*"))
alternativeValue=Combine((VALUE|LSBRKT+delimitedList(VALUE, COMMA)+RSBRKT|LBRKT+delimitedList(VALUE, COMMA) +RBRKT|LSBRKT+VALUE+COLON+VALUE+RSBRKT))("alternativeValue")
parmValue=((EQUAL+alternativeValue|INEQUAL+VALUE))("parmValue")
propertyParm=Group(pkgdName+parmValue)("propertyParm")
extensionParameter=Group(Literal("X")+(Literal("-")|"+")+Word(ALPHA+DIGIT,min=1,max=6))("extensionParameter")
contextIdList=Group(ContextListToken+EQUAL+LBRKT+delimitedList(ContextID, COMMA) +RBRKT)("contextIdList")
contextAttrDescriptor=Group(ContextAttrToken+LBRKT+(contextIdList|delimitedList(propertyParm, COMMA))+RBRKT)("contextAttr")
emergencyValue=Group(EmergencyValueToken+EQUAL+(EmergencyToken|EmergencyOffToken))("emergencyValue")
iepsValue=Group(IEPSToken+EQUAL+(Literal("ON")|"OFF"))("iepsValue")
priority=Group(PriorityToken+EQUAL+UINT16)("priority")
topologyDirection=Group(BothwayToken|IsolateToken|OnewayToken|OnewayExternalToken|OnewayBothToken)("topologyDirection")
TerminationID=(Literal("ROOT")|pathNAME|"$"|"*")("TerminationID")
terminationB=(TerminationID)("terminationB")
terminationA=(TerminationID)("terminationA")
eventStream=Group(StreamToken+EQUAL+StreamID)("eventStream")
topologyTriple=Group(terminationA+COMMA+terminationB+COMMA+topologyDirection+Optional(COMMA+eventStream))("topologyTriple")
topologyDescriptor=Group(TopologyToken+LBRKT+delimitedList(topologyTriple, COMMA)+RBRKT)("topology")
statisticsParameter=Group(pkgdName+Optional(EQUAL+VALUE|(LSBRKT+delimitedList(VALUE, COMMA)+RSBRKT)))("statisticsParameter")
statisticsDescriptor=Group(StatsToken+LBRKT+delimitedList(statisticsParameter, COMMA)+RBRKT)("statistics")
TimeStamp=Group(Date+"T"+Time)("TimeStamp")
packagesItem=Group(NAME+"-"+UINT16)("packagesItem")
Version=Group(Word(DIGIT,min=1,max=2))("Version")
packagesDescriptor=Group(PackagesToken+LBRKT+delimitedList(packagesItem, COMMA)+RBRKT)("packages")
extension=Group(extensionParameter+parmValue)("extension")
serviceChangeVersion=Group(VersionToken+EQUAL+Version)("serviceChangeVersion")
serviceChangeProfile=Group(ProfileToken+EQUAL+NAME+SLASH+Version)("serviceChangeProfile")
deviceName=Group(pathNAME)("deviceName")
TransactionID=UINT32("TransactionID")
ErrorCode=Word(DIGIT,min=1,max=4)("ErrorCode")
mtpAddress=Group(MTPToken+LBRKT+Word(HEXDIG,min=4,max=8)+RBRKT)("mtpAddress")
portNumber=Group(UINT16)("portNumber")
hex4=Group(Word(HEXDIG,min=1,max=4))("hex4")
hexseq=Group(hex4+ZeroOrMore(":"+hex4))("hexseq")
hexpart=Group(hexseq+"::"+Optional(hexseq)|"::"+Optional(hexseq)|hexseq)("hexpart")
V4hex=Group(Word(DIGIT,min=1,max=3))("V4hex")
IPv4address=Group(V4hex+DOT+V4hex+DOT+V4hex+DOT+V4hex)("IPv4address")
IPv6address=Group(hexpart+Optional(":"+IPv4address))("IPv6address")
domainAddress=Group(Literal("[")+(IPv4address|IPv6address)+"]")("domainAddress")
domainName=Group("<"+Word(ALPHA+DIGIT,ALPHA+DIGIT+"-"+".",max=64)+">")("domainName")
mId=(((domainAddress|domainName)+Optional(":"+portNumber))|mtpAddress|deviceName)("mId")
sigIntsigDelay=Group(IntsigDelayToken+EQUAL+UINT16)("sigIntsigDelay")
sigRequestID=(RequestIDToken+EQUAL+RequestID)("sigRequestID")
direction=Group(ExternalToken|InternalToken|BothToken)("direction")
sigDirection=Group(DirectionToken+EQUAL+direction)("sigDirection")
sigDuration=Group(DurationToken+EQUAL+UINT16)("sigDuration")
signalType=Group((OnOffToken|TimeOutToken|BriefToken))("signalType")
sigSignalType=Group(SignalTypeToken+EQUAL+signalType)("sigSignalType")
sigOther=Group(sigParameterName+parmValue)("sigOther")
sigStream=Group(StreamToken+EQUAL+StreamID)("sigStream")
signalName=Group(pkgdName)("signalName")
notificationReason=Group(TimeOutToken|InterruptByEventToken|InterruptByNewSignalsDescrToken|OtherReasonToken|IterationToken)("notificationReason")
notifyCompletion=Group(NotifyCompletionToken+EQUAL+(LBRKT+delimitedList(notificationReason, COMMA)+RBRKT))("notifyCompletion")
sigParameter=Group(sigStream|sigSignalType|sigDuration|sigOther|notifyCompletion|KeepActiveToken|sigDirection|sigRequestID|sigIntsigDelay)("sigParameter")
signalRequest=Group(signalName+Optional(LBRKT+delimitedList(sigParameter, COMMA)+RBRKT))("signalRequest")
signalListParm=Group(signalRequest)("signalListParm")
signalList=Group(SignalListToken+EQUAL+signalListId+LBRKT+delimitedList(signalListParm,COMMA)+RBRKT)("signalList")
signalParm=Group(signalList|signalRequest)("signalParm")
signalsDescriptor=Group(SignalsToken+Optional(LBRKT+delimitedList(signalParm,COMMA)+RBRKT))("signals")
serviceChangeMgcId=(MgcIdToken+EQUAL+mId)("serviceChangeMgcId")
serviceChangeAddress=Group(ServiceChangeAddressToken+EQUAL+(mId|portNumber))("serviceChangeAddress")
serviceChangeDelay=Group(DelayToken+EQUAL+UINT32)("serviceChangeDelay")
serviceChangeReason=Group(ReasonToken+EQUAL+VALUE)("serviceChangeReason")
serviceChangeMethod=Group(MethodToken+EQUAL+(FailoverToken|ForcedToken|GracefulToken|RestartToken|DisconnectedToken|HandOffToken|extensionParameter))("serviceChangeMethod")
servChgReplyParm=Group(serviceChangeAddress|serviceChangeMgcId|serviceChangeProfile|serviceChangeVersion|TimeStamp)("servChgReplyParm")
serviceChangeReplyDescriptor=Group(ServicesToken+LBRKT+delimitedList(servChgReplyParm, COMMA)+RBRKT)("serviceChangeReply")
auditReturnItem=Group((MuxToken|ModemToken|MediaToken|DigitMapToken|StatsToken|ObservedEventsToken|PackagesToken))("auditReturnItem")
indAudpackagesDescriptor=Group(PackagesToken+LBRKT+packagesItem+RBRKT)("indAudpackages")
indAudstatisticsDescriptor=Group(StatsToken+LBRKT+pkgdName+RBRKT)("indAudstatistics")
indAuddigitMapDescriptor=Group(DigitMapToken+EQUAL+(digitMapName))("indAuddigitMap")
indAudsignalRequestParm=Group(sigStream|sigRequestID)("indAudsignalRequestParm")
indAudsignalRequest=Group(signalName+Optional(LBRKT+delimitedList(indAudsignalRequestParm, COMMA)+RBRKT))("indAudsignalRequest")
indAudsignalListParm=Group(indAudsignalRequest)("indAudsignalListParm")
indAudsignalList=Group(SignalListToken+EQUAL+signalListId+Optional(LBRKT+indAudsignalListParm+RBRKT))("indAudsignalList")
indAudsignalParm=Group(indAudsignalList|indAudsignalRequest)("indAudsignalParm")
indAudsignalsDescriptor=Group(SignalsToken+LBRKT+Optional(indAudsignalParm)+RBRKT)("indAudsignals")
indAudrequestedEvent=Group(pkgdName)("indAudrequestedEvent")
indAudeventsDescriptor=Group(EventsToken+Optional(EQUAL+RequestID)+LBRKT+indAudrequestedEvent+RBRKT)("indAudevents")
eventParameterName=Group(NAME)("eventParameterName")
eventOther=Group(eventParameterName+parmValue)("eventOther")
indAudeventSpecParameter=Group(eventStream|eventParameterName)("indAudeventSpecParameter")
indAudeventSpec=Group(pkgdName+Optional(LBRKT+indAudeventSpecParameter+RBRKT))("indAudeventSpec")
indAudeventBufferDescriptor=Group(EventBufferToken+LBRKT+indAudeventSpec+RBRKT)("indAudeventBuffer")
serviceStatesValue=Group((TestToken|OutOfSvcToken|InSvcToken))("serviceStatesValue")
indAudterminationStateParm=Group(pkgdName|propertyParm|ServiceStatesToken+Optional((EQUAL|INEQUAL)+serviceStatesValue)|BufferToken)("indAudterminationStateParm")
indAudterminationStateDescriptor=Group(TerminationStateToken+LBRKT+indAudterminationStateParm+RBRKT)("indAudterminationState")
streamModes=(SendonlyToken|RecvonlyToken|SendrecvToken|InactiveToken|LoopbackToken)("Mode")
indAudlocalParm=Group(ModeToken+Optional((EQUAL|INEQUAL)+streamModes)|pkgdName|propertyParm|ReservedValueToken|ReservedGroupToken)("indAudlocalParm")
indAudlocalControlDescriptor=Group(LocalControlToken+LBRKT+delimitedList(indAudlocalParm, COMMA)+RBRKT)("indAudlocalControl")
indAudstreamParm=Forward()
indAudstreamDescriptor=Group(StreamToken+EQUAL+StreamID+LBRKT+indAudstreamParm+RBRKT)("indAudstream")
indAudlocalDescriptor=Group(LocalToken+LBRKT+octetString+RBRKT)("indAudlocal")
indAudremoteDescriptor=Group(RemoteToken+LBRKT+octetString+RBRKT)("indAudremote")
indAudstreamParm<<(indAudlocalControlDescriptor|indAudstatisticsDescriptor|indAudremoteDescriptor|indAudlocalDescriptor)
indAudmediaParm=indAudstreamParm|indAudstreamDescriptor|indAudterminationStateDescriptor
indAudmediaDescriptor=Group(MediaToken+LBRKT+delimitedList(indAudmediaParm, COMMA)+RBRKT)("indAudmedia")
indAudauditReturnParameter=indAudmediaDescriptor|indAudeventsDescriptor|indAudsignalsDescriptor|indAuddigitMapDescriptor|indAudeventBufferDescriptor|indAudstatisticsDescriptor|indAudpackagesDescriptor
indAudterminationAudit=Group(delimitedList(indAudauditReturnParameter, COMMA))("indAudterminationAudit")
auditItem=Group(auditReturnItem|SignalsToken|EventBufferToken|EventsToken|indAudterminationAudit)("auditItem")
serviceChangeParm=Group(serviceChangeMethod|serviceChangeReason|serviceChangeDelay|serviceChangeAddress|serviceChangeProfile|extension|TimeStamp|serviceChangeMgcId|serviceChangeVersion|ServiceChangeIncompleteToken|auditItem)("serviceChangeParm")
serviceChangeDescriptor=Group(ServicesToken+LBRKT+delimitedList(serviceChangeParm,COMMA)+RBRKT)("serviceChange")
digitMapLetter=DIGIT+srange("[\\0x41-\\0x4B]")+srange("[\\0x61-\\0x6B]")+"L"+"S"+"T"+"Z"
digitLetter=Group(Word(DIGIT+"-"+DIGIT)|Word(digitMapLetter))("digitLetter")
digitMapRange=Group((Literal("x")|(LWSP+"["+LWSP+digitLetter+LWSP+"]"+LWSP)))("digitMapRange")
digitPosition=Group(digitMapLetter|digitMapRange)("digitPosition")
digitStringElement=Group(digitPosition+Optional(DOT))("digitStringElement")
digitString=Group(OneOrMore(digitStringElement))("digitString")
digitStringList=Group(digitString+ZeroOrMore(LWSP+"|"+LWSP+digitString))("digitStringList")
digitMap=Group((digitString|LWSP+"("+LWSP+digitStringList+LWSP+")"+LWSP))("digitMap")
Timer=Group(Word(DIGIT,min=1,max=2))("Timer")
digitMapValue=Group(Optional("T"+COLON+Timer+COMMA)+Optional("S"+COLON+Timer+COMMA)+Optional("L"+COLON+Timer+COMMA)+Optional("Z"+COLON+Timer+COMMA)+digitMap)("digitMapValue")
digitMapDescriptor=Group(DigitMapToken+EQUAL+((LBRKT+digitMapValue+RBRKT)| (digitMapName+Optional(LBRKT+digitMapValue+RBRKT))))("digitMap")
modemType=Group(V32bisToken|V22bisToken|V18Token|V22Token|V32Token|V34Token|V90Token|V91Token|SynchISDNToken|extensionParameter)("modemType")
modemDescriptor=Group(ModemToken+((EQUAL+modemType)|(LSBRKT+delimitedList(modemType, COMMA)+RSBRKT))+Optional(LBRKT+delimitedList(propertyParm, COMMA)+RBRKT))("modem")
observedEventParameter=(eventStream|eventOther)
observedEvent=Group(Optional(TimeStamp+LWSP+COLON)+LWSP+pkgdName+Optional(LBRKT+delimitedList(observedEventParameter,COMMA)+RBRKT))("observedEvent")
observedEventsDescriptor=Group(ObservedEventsToken+EQUAL+RequestID+LBRKT+SkipTo(RBRKT)+RBRKT)("observedEvents")
eventDM=Group(DigitMapToken+EQUAL((digitMapName)|(LBRKT+digitMapValue+RBRKT)))("eventDM")
embedSig=Group(EmbedToken+LBRKT+signalsDescriptor+RBRKT)("embedSig")
secondEventParameter=Forward()
secondRequestedEvent=Group(pkgdName+Optional(LBRKT+delimitedList(secondEventParameter, COMMA)+RBRKT))("secondRequestedEvent")
embedFirst=Group(EventsToken+Optional(EQUAL+RequestID+LBRKT+delimitedList(secondRequestedEvent,COMMA)+RBRKT))("embedFirst")
embedNoSig=Group(EmbedToken+LBRKT+embedFirst+RBRKT)("embedNoSig")
embedWithSig=Group(EmbedToken+LBRKT+signalsDescriptor+Optional(COMMA+embedFirst)+RBRKT)("embedWithSig")
notifyRegulated=Group(NotifyRegulatedToken+Optional(LBRKT+(embedWithSig|embedNoSig)+RBRKT))("notifyRegulated")
notifyBehaviour=Group(NotifyImmediateToken|notifyRegulated|NeverNotifyToken)("notifyBehaviour")
eventParameter=Group((embedWithSig|embedNoSig|KeepActiveToken|eventDM|eventStream|eventOther|notifyBehaviour|ResetEventsDescriptorToken))("eventParameter")
secondEventParameter<<(embedSig|KeepActiveToken|eventDM|eventStream|eventOther|notifyBehaviour|ResetEventsDescriptorToken)
requestedEvent=Group(pkgdName+Optional(LBRKT+delimitedList(eventParameter, COMMA)+RBRKT))("requestedEvent")
eventsDescriptor=Group(EventsToken+Optional(EQUAL+RequestID+LBRKT+delimitedList(requestedEvent,COMMA)+RBRKT))("events")
MuxType=Group((H221Token|H223Token|H226Token|V76Token|extensionParameter|Nx64kToken))("MuxType")
serviceStates=Group(ServiceStatesToken+EQUAL+serviceStatesValue)("serviceStates")
eventBufferControlValue=Group(("OFF"|LockStepToken))("eventBufferControlValue")
eventBufferControl=Group(BufferToken+EQUAL+eventBufferControlValue)("eventBufferControl")
terminationStateParm=Group((propertyParm|serviceStates|eventBufferControl))("terminationStateParm")
terminationStateDescriptor=Group(TerminationStateToken+LBRKT+delimitedList(terminationStateParm, COMMA)+RBRKT)("terminationState")
eventSpecParameter=Group((eventStream|eventOther))("eventSpecParameter")
eventSpec=Group(pkgdName+Optional(LBRKT+delimitedList(eventSpecParameter,COMMA)+RBRKT))("eventSpec")
eventBufferDescriptor=Group(EventBufferToken+Optional(LBRKT+delimitedList(eventSpec, COMMA)+RBRKT))("eventBuffer")
remoteDescriptor=(RemoteToken+LBRKT+octetString+RBRKT)("Remote")
localDescriptor=(LocalToken+LBRKT+octetString+RBRKT)("Local")
streamMode=(ModeToken+EQUAL+streamModes)
reservedGroupMode=Group(ReservedGroupToken+EQUAL+(Literal("ON")|"OFF"))("reservedGroupMode")
reservedValueMode=Group(ReservedValueToken+EQUAL+(Literal("ON")|"OFF"))("reservedValueMode")
localParm=(streamMode|propertyParm|reservedValueMode|reservedGroupMode)
localControlDescriptor=Group(LocalControlToken+LBRKT+delimitedList(localParm,COMMA)+RBRKT)("LocalControl")
localControlDescriptor=Group(LocalControlToken+LBRKT+octetString+RBRKT)("LocalControl")
streamParm=(localDescriptor|remoteDescriptor|localControlDescriptor|statisticsDescriptor)
streamDescriptor=Group(StreamToken+EQUAL+StreamID+LBRKT+delimitedList(streamParm, COMMA)+RBRKT)("Stream")
mediaParm=streamParm|streamDescriptor|terminationStateDescriptor
mediaDescriptor=Group(MediaToken+LBRKT+delimitedList(mediaParm, COMMA)+RBRKT)("Media")
terminationIDList=Group(LBRKT+delimitedList(TerminationID, COMMA)+RBRKT)("terminationIDList")
muxDescriptor=Group(MuxToken+EQUAL+MuxType+terminationIDList)("mux")
termIDList=Group((TerminationID|LSBRKT+TerminationID+OneOrMore(COMMA+TerminationID)+RSBRKT))("termIDList")
errorDescriptor=Group(ErrorToken+EQUAL+ErrorCode+LBRKT+Optional(quotedString)+RBRKT)("error")
serviceChangeReply=Group(ServiceChangeToken+EQUAL+termIDList+Optional(LBRKT+(errorDescriptor|serviceChangeReplyDescriptor)+RBRKT))("serviceChangeReply")
serviceChangeRequest=Group(ServiceChangeToken+EQUAL+termIDList+LBRKT+serviceChangeDescriptor+RBRKT)("serviceChangeRequest")
notifyReply=Group(NotifyToken+EQUAL+termIDList+Optional(LBRKT+errorDescriptor+RBRKT))("notifyReply")
notifyRequest=Group(NotifyToken+EQUAL+termIDList+LBRKT+(observedEventsDescriptor+Optional(COMMA+errorDescriptor))+RBRKT)("notifyRequest")
auditDescriptor=Group(AuditToken+LBRKT+Optional(delimitedList(auditItem,COMMA))+RBRKT)("audit")
auditReturnParameter=(mediaDescriptor|modemDescriptor|muxDescriptor|eventsDescriptor|signalsDescriptor|digitMapDescriptor|observedEventsDescriptor|eventBufferDescriptor|statisticsDescriptor|packagesDescriptor|errorDescriptor|auditReturnItem)
contextTerminationAudit=Group(EQUAL+CtxToken+(terminationIDList|LBRKT+errorDescriptor+RBRKT))("contextTerminationAudit")
terminationAudit=Group(delimitedList(auditReturnParameter,COMMA))("terminationAudit")
auditOther=Group(EQUAL+termIDList+Optional(LBRKT+terminationAudit+RBRKT))("auditOther")
auditReply=Group((AuditValueToken|AuditCapToken)+(contextTerminationAudit|auditOther))("auditReply")
auditRequest=Group((AuditValueToken|AuditCapToken)+EQUAL+termIDList+LBRKT+auditDescriptor+RBRKT)("auditRequest")
subtractRequest=Group(SubtractToken+EQUAL+termIDList+Optional(LBRKT+auditDescriptor+RBRKT))("subtractRequest")
ammsReply=Group((AddToken|MoveToken|ModifyToken|SubtractToken)+EQUAL+termIDList+Optional(LBRKT+terminationAudit+RBRKT))("ammsReply")
ammParameter=mediaDescriptor|modemDescriptor|muxDescriptor|eventsDescriptor|signalsDescriptor|digitMapDescriptor|eventBufferDescriptor|auditDescriptor|statisticsDescriptor
ammRequestBody=EQUAL+termIDList+Optional(LBRKT+delimitedList(ammParameter, COMMA)+RBRKT)
ammRequest=Group((MoveToken|ModifyToken)+ ammRequestBody )("ammRequest")
addRequest=Group(AddToken + ammRequestBody)("Add")
segmentNumber=UINT16("segmentNumber")
segmentReply=Group(MessageSegmentToken+EQUAL+TransactionID+SLASH+segmentNumber+Optional(SLASH+SegmentationCompleteToken))("segmentReply")
commandRequest=addRequest| ammRequest | subtractRequest|auditRequest|notifyRequest|serviceChangeRequest
commandRequestList=delimitedList(Optional("O-")+Optional("W-")+commandRequest, COMMA)
AndAUDITselectToken=Group(Literal("TODO"))("AndAUDITselectToken")
OrAUDITselectToken=Group(Literal("TODO"))("OrAUDITselectToken")
auditSelectLogic=Group(Optional(AndAUDITselectToken|OrAUDITselectToken))("auditSelectLogic")
contextAuditSelector=Group(priority|emergencyValue|iepsValue|contextAttrDescriptor|auditSelectLogic)("contextAuditSelector")
contextAuditProperties=Group((TopologyToken|EmergencyToken|PriorityToken|IEPSToken|pkgdName|contextAuditSelector))("contextAuditProperties")
indAudcontextAttrDescriptor=Group(ContextAttrToken+LBRKT+delimitedList(contextAuditProperties, COMMA)+RBRKT)("indAudcontextAttr")
contextAudit=Group(ContextAuditToken+LBRKT+(delimitedList(contextAuditProperties,COMMA))|indAudcontextAttrDescriptor+RBRKT)("contextAudit")
contextProperty=Group((topologyDescriptor|priority|EmergencyToken|EmergencyOffToken|iepsValue|contextAttrDescriptor))("contextProperty")
contextProperties=Group(delimitedList(contextProperty,COMMA))("contextProperties")
commandReplys=(serviceChangeReply|auditReply|ammsReply|notifyReply)
commandReplyList=Group(delimitedList(commandReplys,COMMA))("commandReplyList")
commandReply=Group(((contextProperties+Optional(COMMA+commandReplyList))|commandReplyList))("commandReply")
actionReply=Group(CtxToken+EQUAL+ContextID+Optional(LBRKT+(errorDescriptor|commandReply|(commandReply+COMMA+errorDescriptor))+RBRKT))("actionReply")
actionReplyList=Group(delimitedList(actionReply,COMMA))("actionReplyList")
transactionReply=Group(ReplyToken+EQUAL+TransactionID+Optional(SLASH+segmentNumber+Optional(SLASH+SegmentationCompleteToken))+LBRKT+Optional(ImmAckRequiredToken+COMMA)+(errorDescriptor|actionReplyList)+RBRKT)("TransactionReply")
contextRequest=Group(((contextProperties+Optional(COMMA+contextAudit))|contextAudit))("contextRequest")
actionRequest=Group(CtxToken+EQUAL+ContextID+LBRKT+((contextRequest+Optional(COMMA+commandRequestList))|commandRequestList)+RBRKT)("actionRequest")
transactionRequest=Group(TransToken+EQUAL+TransactionID+LBRKT+delimitedList(actionRequest, COMMA)+RBRKT)("TransactionRequest")
transactionAck=Group(TransactionID|(TransactionID+"-"+TransactionID))("TransactionAck")
transactionResponseAck=Group(ResponseAckToken+LBRKT+transactionAck+ZeroOrMore(COMMA+transactionAck)+RBRKT)("transactionResponseAck")
transactionPending=Group(PendingToken+EQUAL+TransactionID+LBRKT+RBRKT)("transactionPending")
transactionList=OneOrMore(transactionRequest|transactionReply|transactionPending|transactionResponseAck|segmentReply)
messageBody=(transactionList | errorDescriptor)
Message=Group(MegacopToken+SLASH+Version+SkipTo(lineEnd)+messageBody)("Message")
AuthData=Group("0x"+Word(HEXDIG,min=24,max=64))("AuthData")
SequenceNum=Group("0x"+Word(HEXDIG,exact=8))("SequenceNum")
SecurityParmIndex=Group("0x"+Word(HEXDIG,exact=8))("SecurityParmIndex")
authenticationHeader=Group(AuthToken+EQUAL+SecurityParmIndex+COLON+SequenceNum+COLON+AuthData)("authenticationHeader")
megacoMessage=Group(LWSP+Optional(authenticationHeader+SEP)+Message)("megacoMessage").streamline()
