def __init__(s): s.LT = L("<") s.GT = L(">") s.EQ = L("=") s.LPARN = S("(") s.RPARN = S(")") s.LBRAC = S("{") s.RBRAC = S("}") s.EquivOp = L("<==>") s.ImplOp = L("==>") s.OrOp = L("||") s.AndOp = L("&&") s.RelOp = (L("!=") | L ("<=") | L(">=") | L("<:")| L("==") | \ L("<") | L(">") ) s.AddOp = (L("+") | L("-")) s.MulOp = (L("*") | L("/") | L("%")) s.BWAnd = L('&') s.PowOp = L("**") s.UnOp = (L("!") | L("-")) s.FALSE = K("false") s.FALSE.setParseAction( lambda st, loc, toks: s.onAtom(s.FALSE, st, loc, toks)) s.TRUE = K("true") s.TRUE.setParseAction( lambda st, loc, toks: s.onAtom(s.TRUE, st, loc, toks)) s.Id = R("[a-zA-Z_][a-zA-Z0-9_#]*") s.Id.setParseAction( lambda st, loc, toks: s.onAtom(s.Id, st, loc, toks)) s.Number = W(nums) s.Number.setParseAction( lambda st, loc, toks: s.onAtom(s.Number, st, loc, toks)) s.Atom = s.FALSE | s.TRUE | s.Number | s.Id s.AndOrOp = s.AndOp | s.OrOp s.ArithExpr = operatorPrecedence(s.Atom, [ (s.PowOp, 2, opAssoc.RIGHT, lambda st, loc, toks: s.onRABinOp(s.PowOp, st, loc, toks[0])), (s.UnOp, 1, opAssoc.RIGHT, lambda st, loc, toks: s.onUnaryOp(s.UnOp, st, loc, toks[0])), (s.MulOp, 2, opAssoc.LEFT, lambda st, loc, toks: s.onLABinOp(s.MulOp, st, loc, toks[0])), (s.AddOp, 2, opAssoc.LEFT, lambda st, loc, toks: s.onLABinOp(s.MulOp, st, loc, toks[0])), ]) s.RelExpr = s.ArithExpr + s.RelOp + s.ArithExpr s.RelExpr.setParseAction( lambda st, loc, toks: s.onNABinOp(s.RelOp, st, loc, toks)) s.BoolExpr = operatorPrecedence(s.RelExpr, [ (s.AndOrOp, 2, opAssoc.LEFT, lambda st, loc, toks: s.onLABinOp(s.AndOrOp, st, loc, toks[0])), (s.ImplOp, 2, opAssoc.LEFT, lambda st, loc, toks: s.onLABinOp(s.ImplOp, st, loc, toks[0])), (s.EquivOp, 2, opAssoc.LEFT, lambda st, loc, toks: s.onLABinOp(s.EquivOp, st, loc, toks[0])), ]) s.Expr = s.BoolExpr | s.RelExpr | s.ArithExpr s.IsPow2 = s.Id + S("is a power of 2") s.IsPow2.setParseAction( lambda st, loc, toks: s.onUnaryOp(s.IsPow2, st, loc, toks)) s.IsOneOf = s.Id + S("one of") + S(s.LBRAC) + csl(s.Expr) + S(s.RBRAC) s.IsOneOf.setParseAction(lambda st, loc, toks: s.onNABinOp( s.IsOneOf, st, loc, [toks[0], toks[1:]])) s.IsInRange = s.Number + S(L("<=")) + s.Id + S(L("<=")) + s.Number s.IsInRange.setParseAction( lambda st, loc, toks: s.onNABinOp(s.IsInRange, st, loc, toks)) s.IsBoolean = s.Id + S(L("is boolean")) s.IsBoolean.setParseAction( lambda st, loc, toks: s.onUnaryOp(s.IsBoolean, st, loc, toks)) s.IsEven = s.Id + S(L("is even")) s.IsEven.setParseAction( lambda st, loc, toks: s.onUnaryOp(s.IsEven, st, loc, toks)) s.IsConstMod = s.Id + S(L("==")) + s.Number + \ S(L("(mod")) + s.Number + S(L(")")) s.IsConstMod.setParseAction( lambda st, loc, toks: s.onTernaryOp(s.IsConstMod, st, loc, toks)) ValFreqPair = s.ArithExpr + S(L("[") + s.Number + L("]")) s.HasValues = s.Id + S(L("has values:")) + OneOrMore(ValFreqPair) s.HasValues.setParseAction( lambda st, loc, toks: s.onVariaryOp(s.HasValues, st, loc, toks)) s.JustInv = s.IsPow2 |\ s.IsOneOf |\ s.IsInRange |\ s.IsBoolean |\ s.IsEven |\ s.IsConstMod |\ s.HasValues |\ s.Expr s.WarnInv = S(R("warning: too few samples for [a-zA-Z\._]* invariant:")) + \ s.JustInv | s.JustInv s.OneLine = s.WarnInv + StringEnd()
def __init__(s) -> None: s.LT = L("<") s.GT = L(">") s.EQ = L("=") # Braces/Brackets s.LSQBR = S("[") s.RSQBR = S("]") s.LPARN = S("(") s.RPARN = S(")") s.LBRAC = S("{") s.RBRAC = S("}") # Various Delimiters s.SEMI = S(";") s.COLN = S(":") s.ASSGN = S(":=") s.STAR = S("*") ####### Keywords s.INT = K("int") s.BOOL = K("bool") s.TYPE = K("type") s.FINITE = K("finite") s.CONST = K("const") s.UNIQUE = K("unique") s.RETURNS = K("returns") s.FUNCTION = K("function") s.FALSE = K("false") # type: ParserElement[T] s.FALSE.setParseAction(\ lambda st, loc, toks: s.onAtom(s.FALSE, st, loc, toks)) s.TRUE = K("true") # type: ParserElement[T] s.TRUE.setParseAction(\ lambda st, loc, toks: s.onAtom(s.TRUE, st, loc, toks)) s.OLD = K("old") s.AXIOM = K("axiom") s.FORALL = K("forall") s.EXISTS = K("exists") s.VAR = K("var") s.PROCEDURE = K("procedure") s.FREE = K("free") s.RETURNS = K("returns") s.REQUIRES = K("requires") s.MODIFIES = K("modifies") s.ENSURES = K("ensures") s.ASSERT = K("assert") s.COMPLETE = K("complete") s.UNIQUE = K("unique") s.IF = K("if") s.ELSE = K("else") s.FREE = K("free") s.INVARIANT = K("invariant") s.ASSUME = K("assume") s.ASSERT = K("assert") s.HAVOC = K("havoc") s.CALL = K("call") s.WHILE = K("while") s.BREAK = K("break") s.GOTO = K("goto") s.RETURN = K("return") s.IMPLEMENTATION = K("implementation") s.Id = R("[a-zA-Z_#.$'`~^?\\\\][a-zA-Z0-9_#.$'`~^?\\\\]*" ) # type: ParserElement[T] s.Id.setParseAction( lambda st, loc, toks: s.onAtom(s.Id, st, loc, toks)) s.ParentEdge = O(s.UNIQUE) + s.Id s.ParentInfo = S("<:") + csl(s.ParentEdge) s.OrderSpec = O(s.ParentInfo) + O(s.COMPLETE) s.StringLiteral = S(L("\"")) + R("[^\"]*") + S(L("\"")) s.Trigger = F() # TODO ####### Expressions s.EquivOp = L("<==>") s.ImplOp = L("==>") s.OrOp = L("||") s.AndOp = L("&&") s.AndOrOp = s.AndOp | s.OrOp s.RelOp = (L("!=") | L ("<=") | L(">=") | L("<:") \ | L("==") | L("<") | L(">") ) s.ConcatOp = L("++") s.AddOp = (L("+") | L("-")) s.MulOp = (L("*") | L("/") | L("div") | L("mod")) s.UnOp = (L("!") | L("-")) s.ArithUnOp = L("-") s.BoolUnOp = L("!") s.QOp = (s.FORALL | s.EXISTS) s.QSep = L("::") s.Expr = F() # type: ParserElement[T] ####### Attributes s.AttrArg = s.Expr | s.StringLiteral s.Attribute = S(s.LBRAC) + S(s.COLN) + s.Id + G(O(csl(s.AttrArg))) + S( s.RBRAC) s.Attribute.setParseAction( lambda st, loc, toks: s.onAttribute(s.Attribute, st, loc, toks)) s.AttrList = ZoM(s.Attribute) ####### Types s.Type = F() # type: ParserElement[T] s.BVType = R("bv[0-9][0-9]*") s.INT.setParseAction( lambda st, loc, toks: s.onPrimitiveType(s.INT, st, loc, toks)) s.BOOL.setParseAction( lambda st, loc, toks: s.onPrimitiveType(s.BOOL, st, loc, toks)) s.BVType.setParseAction( lambda st, loc, toks: s.onPrimitiveType(s.BVType, st, loc, toks)) s.TypeAtom = s.INT | s.BOOL | s.BVType | S(s.LPARN) + s.Type + S( s.RPARN) s.TypeArgs = S(s.LT) + csl(s.Id) + S(s.GT) s.MapType = G(O(s.TypeArgs)) + S(s.LSQBR) + G(csl(s.Type)) + S( s.RSQBR) + s.Type s.MapType.setParseAction( lambda st, loc, toks: s.onMapType(s.Type, st, loc, toks)) s.TypeCtorArgs = F() s.TypeCtorArgs << (s.TypeAtom + O(s.TypeCtorArgs)\ | s.Id + O(s.TypeCtorArgs)\ | s.MapType) s.CompoundType = s.Id + O(s.TypeCtorArgs) s.CompoundType.setParseAction(lambda st, loc, toks: s.onCompoundType( s.CompoundType, st, loc, toks)) s.Type << (s.TypeAtom | s.MapType | s.CompoundType) #pylint: disable=expression-not-assigned s.Type.setParseAction( lambda st, loc, toks: s.onType(s.Type, st, loc, toks)) s.IdsType = csl(s.Id) + s.COLN + s.Type s.IdsType.setParseAction( lambda st, loc, toks: s.onBinding(s.Type, st, loc, toks)) ####### Type Declarations s.TypeConstructor = S(s.TYPE) + G(s.AttrList) + G(O( s.FINITE)) + s.Id + G(ZoM(s.Id)) + S(s.SEMI) s.TypeConstructor.setParseAction( lambda st, loc, toks: s.onTypeConstructorDecl( s.TypeConstructor, st, loc, toks)) s.TypeSynonym = s.TYPE + s.AttrList + OoM( s.Id) + s.EQ + s.Type + s.SEMI s.TypeDecl = s.TypeConstructor | s.TypeSynonym ####### Constant Declarations s.ConstantDecl = s.CONST + O(s.Attribute) + O(s.UNIQUE) + \ s.IdsType + s.OrderSpec s.Number = W(nums) # type: ParserElement[T] s.Number.setParseAction( lambda st, loc, toks: s.onAtom(s.Number, st, loc, toks)) s.BitVector = R("[0-9][0-9]*bv[0-9][0-9]*") # type: ParserElement[T] s.BitVector.setParseAction( lambda st, loc, toks: s.onAtom(s.BitVector, st, loc, toks)) # TODO # TrigAttr = Trigger | Attribute s.Old = s.OLD + s.LPARN + s.Expr + s.RPARN # type: ParserElement[T] s.Old.setParseAction( lambda st, loc, toks: s.onAtom(s.Old, st, loc, toks)) s.Primitive = s.FALSE | s.TRUE | s.Number | s.BitVector # type: ParserElement[T] # TODO: Handle TriggerAttrs in Quantified expressions #E9_Quantified = LPARN + QOp + O(TypeArgs) + csl(IdsType) \ # + QSep + ZoM(TrigAttr) + Expr + RPARN s.Quantified = S(s.LPARN) + s.QOp + O(s.TypeArgs) + \ G(csl(s.IdsType)) + S(s.QSep) + s.Expr + S(s.RPARN) s.Quantified.setParseAction( lambda st, loc, toks: s.onQuantified(s.Old, st, loc, toks)) s.AtomIdCont = F() s.AtomId = s.Id + O(s.AtomIdCont) s.AtomId.setParseAction( lambda st, loc, toks: s.onAtom(s.Id, st, loc, toks)) s.Atom = (s.Primitive | s.Old | s.AtomId) # type: ParserElement[T] s.MapUpdateArgs = S(s.LSQBR) + s.Expr + s.ASSGN + s.Expr + S(s.RSQBR) s.MapUpdateArgs.setParseAction( lambda st, loc, toks: s.onMapUpdateArgs(s.Old, st, loc, toks)) s.MapIndexArgs = S(s.LSQBR) + s.Expr + S(s.RSQBR) s.MapIndexArgs.setParseAction( lambda st, loc, toks: s.onMapIndexArgs(s.Old, st, loc, toks)) s.FunAppArgs = s.LPARN + csl( s.Expr) + s.RPARN # type: ParserElement[T] s.FunAppArgs.setParseAction( lambda st, loc, toks: s.onFunAppArgs(s.FunAppArgs, st, loc, toks)) s.AtomIdCont << (s.MapUpdateArgs | s.MapIndexArgs | s.FunAppArgs) + O( s.AtomIdCont) s.ArithExpr = operatorPrecedence(s.Atom, [ (s.ArithUnOp, 1, opAssoc.RIGHT, \ lambda st, loc, toks: s.onUnaryOp(s.ArithUnOp, st, loc, toks[0])), (s.MulOp, 2, opAssoc.LEFT, \ lambda st, loc, toks: s.onLABinOp(s.MulOp, st, loc, toks[0])), (s.AddOp, 2, opAssoc.LEFT, \ lambda st, loc, toks: s.onLABinOp(s.AddOp, st, loc, toks[0])), ]) # type: ParserElement[T] # TODO: Add support for M[x,y,z:=foo], M[a:b], concat ops s.RelExpr = s.ArithExpr + s.RelOp + s.ArithExpr # type: ParserElement[T] s.RelExpr.setParseAction( lambda st, loc, toks: s.onNABinOp(s.RelExpr, st, loc, toks)) s.BoolExpr = operatorPrecedence((s.RelExpr | s.Atom | s.Quantified), [ (s.BoolUnOp, 1, opAssoc.RIGHT, \ lambda st, loc, toks: s.onUnaryOp(s.BoolUnOp, st, loc, toks[0])), (s.AndOrOp, 2, opAssoc.LEFT, \ lambda st, loc, toks: s.onLABinOp(s.AndOrOp, st, loc, toks[0])), (s.ImplOp, 2, opAssoc.LEFT, \ lambda st, loc, toks: s.onLABinOp(s.ImplOp, st, loc, toks[0])), (s.EquivOp, 2, opAssoc.LEFT, \ lambda st, loc, toks: s.onLABinOp(s.EquivOp, st, loc, toks[0])), ]) # type: ParserElement[T] s.Expr << (s.BoolExpr ^ s.RelExpr ^ s.ArithExpr) #pylint: disable=pointless-statement ####### Function Declarations s.FArgName = s.Id + s.COLN s.FArg = s.FArgName + s.Type s.FSig = O(s.TypeArgs) + s.LPARN + csl(s.FArg) + \ s.RPARN + s.RETURNS + s.LPARN + s.FArg + s.RPARN s.FunctionDecl = s.FUNCTION + s.AttrList + s.Id + s.FSig + s.SEMI |\ s.FUNCTION + s.AttrList + s.Id + s.FSig + s.SEMI +\ s.LBRAC + s.Expr + s.RBRAC ####### Axiom Declarations s.AxiomDecl = s.AXIOM + s.AttrList + s.Expr s.WhereClause = F() # TODO s.IdsTypeWhere = s.IdsType + O(s.WhereClause) s.VarDecl = s.VAR + s.AttrList + s.IdsTypeWhere ####### Procedure Declarations s.Spec = O(s.FREE) + s.REQUIRES + s.Expr + s.SEMI \ | O(s.FREE) + s.MODIFIES + csl(s.Id) + s.SEMI \ | O(s.FREE) + s.ENSURES + s.Expr + s.SEMI s.OutParameters = s.RETURNS + s.LPARN + csl(s.IdsTypeWhere) + s.RPARN s.PSig = O(s.TypeArgs) + s.LPARN + csl(s.IdsTypeWhere) + \ s.RPARN + O(s.OutParameters) s.LocalVarDecl = S(s.VAR) + s.AttrList + csl(s.IdsTypeWhere) + \ S(s.SEMI) # type: ParserElement[T] s.LocalVarDecl.setParseAction(lambda st, loc, toks: s.onLocalVarDecl( s.LocalVarDecl, st, loc, toks)) s.StmtList = F() s.WildcardExpr = s.Expr | s.STAR s.BlockStmt = s.LBRAC + s.StmtList + s.RBRAC s.LoopInv = O(s.FREE) + s.INVARIANT + s.Expr + s.SEMI s.IfStmt = F() # type: Union[F, ParserElement[T]] s.Else = s.ELSE + s.BlockStmt | s.ELSE + s.IfStmt s.IfStmt << s.IF + s.LBRAC + s.WildcardExpr + s.RBRAC + s.BlockStmt + \ O(s.Else) s.CallLhs = csl(s.Id) + s.ASSGN s.Lhs = s.Id + ZoM(s.MapIndexArgs) s.Lhs.setParseAction( lambda st, loc, toks: s.onAtom(s.Id, st, loc, toks)) s.Label = s.Id | s.Number s.AssertStmt = S(s.ASSERT) + s.Expr + S( s.SEMI) # type: ParserElement[T] s.AssertStmt.setParseAction( lambda st, loc, toks: s.onAssert(s.AssertStmt, st, loc, toks)) s.AssumeStmt = S(s.ASSUME) + G(s.AttrList) + s.Expr + S( s.SEMI) # type: ParserElement[T] s.AssumeStmt.setParseAction( lambda st, loc, toks: s.onAssume(s.AssumeStmt, st, loc, toks)) s.ReturnStmt = S(s.RETURN) + S(s.SEMI) # type: ParserElement[T] s.ReturnStmt.setParseAction( lambda st, loc, toks: s.onReturn(s.ReturnStmt, st, loc, toks)) s.GotoStmt = S(s.GOTO) + csl(s.Label) + S( s.SEMI) # type: ParserElement[T] s.GotoStmt.setParseAction( lambda st, loc, toks: s.onGoto(s.GotoStmt, st, loc, toks)) s.AssignmentStmt = G(csl(s.Lhs)) + S(s.ASSGN) + G(csl(s.Expr)) + S( s.SEMI) # type: ParserElement[T] s.AssignmentStmt.setParseAction(lambda st, loc, toks: s.onAssignment( s.AssignmentStmt, st, loc, toks)) s.HavocStmt = S(s.HAVOC) + csl(s.Id) + S( s.SEMI) # type: ParserElement[T] s.HavocStmt.setParseAction( lambda st, loc, toks: s.onHavoc(s.HavocStmt, st, loc, toks)) s.CallAssignStmt = s.CALL + O(s.CallLhs) + s.Id + s.LPARN + csl(s.Expr) +\ s.RPARN + S(s.SEMI) s.CallForallStmt = s.CALL + s.FORALL + s.Id + s.LPARN + \ csl(s.WildcardExpr) + s.RPARN + S(s.SEMI) s.WhileStmt = s.WHILE + s.LPARN + s.WildcardExpr + s.RPARN + \ ZoM(s.LoopInv) + s.BlockStmt s.BreakStmt = s.BREAK + O(s.Id) + S(s.SEMI) s.Stmt = s.AssertStmt \ | s.AssumeStmt \ | s.HavocStmt \ | s.AssignmentStmt \ | s.CallAssignStmt \ | s.CallForallStmt \ | s.IfStmt \ | s.WhileStmt \ | s.BreakStmt \ | s.ReturnStmt \ | s.GotoStmt # type: ParserElement[T] s.LStmt = F() s.LabeledStatement = s.Label + S( s.COLN) + s.LStmt # type: ParserElement[T] s.LEmpty = (s.Label + S(s.COLN)) s.LStmt << (s.Stmt | s.LabeledStatement | s.LEmpty) #pylint: disable=pointless-statement s.LabeledStatement.setParseAction( lambda st, loc, toks: s.onLabeledStatement(s.LabeledStatement, st, loc, toks)) s.LEmpty.setParseAction(lambda st, loc, toks: s.onLabeledStatement( s.LEmpty, st, loc, toks)) s.StmtList << (ZoM(s.LStmt)) #pylint: disable=expression-not-assigned s.Body = S(s.LBRAC) + G(ZoM(s.LocalVarDecl)) + G(s.StmtList) + S( s.RBRAC) # type: ParserElement[T] s.Body.setParseAction( lambda st, loc, toks: s.onBody(s.Body, st, loc, toks)) s.ProcedureDecl = \ s.PROCEDURE + s.AttrList + s.Id + s.PSig + s.SEMI + ZoM(s.Spec) |\ s.PROCEDURE + s.AttrList + s.Id + s.PSig + ZoM(s.Spec) + s.Body s.IOutParameters = S(s.RETURNS) + S(s.LPARN) + csl(s.IdsType) + S( s.RPARN) s.ISig = G(O(s.TypeArgs)) + S(s.LPARN) + G(O(csl(s.IdsType))) + S(s.RPARN) +\ G(O(s.IOutParameters)) s.ImplementationDecl = S(s.IMPLEMENTATION) + G(s.AttrList) + s.Id +\ G(s.ISig) + G(ZoM(s.Body)) # type: ParserElement[T] s.ImplementationDecl.setParseAction( lambda st, loc, toks: s.onImplementationDecl( s.ImplementationDecl, st, loc, toks)) s.Decl : ParserElement[T] = s.TypeDecl |\ s.ConstantDecl |\ s.FunctionDecl |\ s.AxiomDecl |\ s.VarDecl |\ s.ProcedureDecl |\ s.ImplementationDecl s.Program = ZoM(s.Decl) # type: ParserElement[T] s.Program.setParseAction( lambda st, loc, toks: s.onProgram(s.Program, st, loc, toks)) s.Program.ignore("//" + restOfLine)
except Exception as e: if fail_fast: raise logging.exception(e) m_true = K('True') m_false = K('False') m_literal = m_true ^ m_false test('m_literal', ''' True False ''') m_identifier = W(initChars=alphas + alphas8bit + '_', bodyChars=alphas + alphas8bit + '_' + nums) m_identifier.setName('NAME') test('m_identifier', ''' a abc _abc abc1 ''') m_and = K('and') m_and.setName('AND') m_or = K('or') m_or.setName('OR') m_not = K('not')
# license which can be found in the file 'LICENSE' in this package distribution. from pyparsing import alphas, alphanums, OneOrMore, Group, Literal, delimitedList from pyparsing import Suppress as S from pyparsing import Optional as O from pyparsing import Word as W from pyparsing import CaselessLiteral as CL from subprocess import check_output ''' Parser of CCF for message and grouped avp ''' digits = '0123456789' mul = Group(O(W(digits)) + '*' + O(W(digits))) fixed_avp = '<' + W(alphanums + '_-') + '>' mandatory_avp = '{' + W(alphanums + '_-') + '}' optional_avp = '[' + W(alphanums + '_-') + ']' avp = Group(O(mul) + (fixed_avp | mandatory_avp | optional_avp)) avps = Group(OneOrMore(avp)) flags = Group(delimitedList(Literal('REQ')|Literal('PXY')|Literal('ERR'), delim=',')) msg_decl = O(S('<')) + W(alphas + '_-') + O(S('>')) msg_hdr = S('<') + S(CL('Diameter')) + S(O('-')) + S(CL('Header')) + S(':') + W(alphanums) + O(S(',')) + flags + O(S(',') + W(alphanums)) + S('>') equals = S(':') + S(':') + S('=') msg_ccf = msg_decl + equals + msg_hdr + avps
success_fail = [0, 0] l = [x.strip() for x in tests.split('\n') if x.strip() != ''] for test in l: print test, ':', try: print toker.parseString(test) success_fail[0] += 1 except Exception as e: if fail_fast: raise logging.exception(e) success_fail[1] += 1 m_integer = Optional('-') + W(nums) m_integer.setName('INT') m_string = quotedString m_string.setName('STR') m_literal = m_integer ^ m_string m_identifier = W(initChars=alphas + alphas8bit + '_', bodyChars=alphas + alphas8bit + '_' + nums) m_identifier.setName('NAME') test('m_identifier', ''' a abc _abc abc1