common.versioncheck.parser

Parser for mini-language specifying profile and class requirements. We call the language LMIReSpL (openLMI Requirement Specification Language).

The only thing designed for use outside this module is bnf_parser().

Language is generated by BNF grammer which served as a model for parser.

Formal representation of BNF grammer is following:

expr          ::= term [ op expr ]*
term          ::= '!'? req
req           ::= profile_cond | clsreq_cond | '(' expr ')'
profile_cond  ::= 'profile'? [ profile | profile_quot ] cond?
clsreq_cond   ::= 'class' [ clsname | clsname_quot] cond?
profile_quot  ::= '"' /\w+[ +.a-zA-Z0-9_-]*/ '"'
profile       ::= /\w+[+.a-zA-Z_-]*/
clsname_quot  ::= '"' clsname '"'
clsname       ::= /[a-zA-Z]+_[a-zA-Z][a-zA-Z0-9_]*/
cond          ::= cmpop version
cmpop         ::= /(<|=|>|!)=|<|>/
version       ::= /[0-9]+(\.[0-9]+)*/
op            ::= '&' | '|'

String surrounded by quotes is a literal. String enclosed with slashes is a regular expression. Square brackets encloses a group of words and limit the scope of some operation (like iteration).

class lmi.scripts.common.versioncheck.parser.And(fst, snd)

Represents logical AND of two expressions. Short-circuit evaluation is being exploited here.

Parameters:
  • fst – An object of Term non-terminal.
  • snd – An object of Term non-terminal.
class lmi.scripts.common.versioncheck.parser.Expr(term)

Initial non-terminal. Object of this class (or one of its subclasses) is a result of parsing.

Parameters:term – An object of Term non-terminal.
lmi.scripts.common.versioncheck.parser.OP_MAP = {'>=': <built-in function ge>, '==': <built-in function eq>, '<=': <built-in function le>, '!=': <built-in function ne>, '<': <built-in function lt>, '>': <built-in function gt>}

Dictionary mapping supported comparison operators to a pair. First item is a function making the comparison and the second can be of two values (all or any). Former sayes that each part of first version string must be in relation to corresponding part of second version string in order to satisfy the condition. The latter causes the comparison to end on first satisfied part.

class lmi.scripts.common.versioncheck.parser.Or(fst, snd)

Represents logical OR of two expressions. Short-circuit evaluation is being exploited here.

Parameters:
  • fst – An object of Term non-terminal.
  • snd – An object of Term non-terminal.
class lmi.scripts.common.versioncheck.parser.Req

Represents one of following subexpressions:

  • single requirement on particular profile
  • single requirement on particular class
  • a subexpression
class lmi.scripts.common.versioncheck.parser.ReqCond(kind, version_getter, name, cond=None)

Represents single requirement on particular class or profile.

Parameters:
  • kind (str) – Name identifying kind of thing this belongs. For example 'class' or 'profile'.
  • version_getter (callable) – Is a function called to get version of either profile or CIM class. It must return corresponding version string if the profile or class is registered and None otherwise. Version string is read from RegisteredVersion property of CIM_RegisteredProfile. If a class is being queried, version shall be taken from Version qualifier of given class.
  • name (str) – Name of profile or CIM class to check for. In case of a profile, it is compared to RegisteredName property of CIM_RegisteredProfile. If any instance of this class has matching name, it’s version will be checked. If no matching instance is found, instances of CIM_RegisteredSubProfile are queried the same way. Failing to find it results in False.
  • cond (str) – Is a version requirement. Check the grammer above for cond non-terminal.
class lmi.scripts.common.versioncheck.parser.SemanticGroup

Base class for non-terminals. Just a minimal set of non-terminals is represented by objects the rest is represented by strings.

All subclasses need to define their own evaluate() method. The parser builds a tree of these non-terminals with single non-terminal being a root node. This node’s evaluate method returns a boolean saying whether the condition is satisfied. Root node is always an object of Expr.

evaluate()
Returns:True if the sub-condition represented by this non-terminal is satisfied.
Return type:boolean
class lmi.scripts.common.versioncheck.parser.Subexpr(expr)

Represents a subexpression originally enclosed in brackets.

class lmi.scripts.common.versioncheck.parser.Term(req, negate)

Represents possible negation of expression.

Parameters:
  • req – An object of Req.
  • negate (boolean) – Whether the result of children shall be negated.
class lmi.scripts.common.versioncheck.parser.TreeBuilder(stack, profile_version_getter, class_version_getter)

A stack interface for parser. It defines methods modifying the stack with additional checks.

expr(strg, loc, toks)

Operates upon a stack. It takes either one or two terms there and makes an expression object out of them. Terms need to be delimited with logical operator.

push_class(strg, loc, toks)

Handles clsreq_cond non-terminal in one go. It extracts corresponding tokens and pushes an object of ReqCond to a stack.

push_literal(strg, loc, toks)

Pushes operators to a stack.

push_profile(strg, loc, toks)

Handles profile_cond non-terminal in one go. It behaves in the same way as push_profile().

subexpr(strg, loc, toks)

Operates upon a stack. It creates an instance of Subexpr out of Expr which is enclosed in brackets.

term(strg, loc, toks)

Creates a term out of requirement (req non-terminal).

lmi.scripts.common.versioncheck.parser.bnf_parser(stack, profile_version_getter, class_version_getter)

Builds a parser operating on provided stack.

Parameters:
  • stack (list) – Stack to operate on. It will contain the resulting Expr object when the parsing is successfully over - it will be the only item in the list. It needs to be initially empty.
  • profile_version_getter (callable) – Function returning version of registered profile or None if not present.
  • class_version_getter (callable) – Fucntion returning version of registered class or None if not present.
Returns:

Parser object.

Return type:

pyparsing,ParserElement

lmi.scripts.common.versioncheck.parser.cmp_version(fst, snd, opsign='<')

Compare two version specifications. Each version string shall contain digits delimited with dots. Empty string is also valid version. It will be replaced with -1.

Parameters:
  • fst (str) – First version string.
  • snd (str) – Second version string.
  • opsign (str) – Sign denoting operation to be used. Supported signs are present in OP_MAP.
Returns:

True if the relation denoted by particular operation exists between two operands.

Return type:

boolean