def get_parser(self, EXPRESSION): result = Suppress(self._name) + Suppress('(') + EXPRESSION for i in range(1, self._n_args): result += Suppress(',') + EXPRESSION result += Suppress(')') result.setName('Function({name})'.format(name=self._name)) result.setParseAction(self) return result
def get_parser(self, EXPRESSION): if isinstance(self.value, str): result = Suppress(self.value) result.setName('NamedConstant({value})'.format(value=self.value)) result.setParseAction(self) return result else: # TODO Detect constants? return None
CharsNotIn, Combine, StringStart, \ StringEnd, delimitedList import string filter_ = Forward() attr = Word( string.ascii_letters, string.ascii_letters + string.digits + ';-', ) attr.leaveWhitespace() attr.setName('attr') hexdigits = Word(string.hexdigits, exact=2) hexdigits.setName('hexdigits') escaped = Suppress(Literal('\\')) + hexdigits escaped.setName('escaped') def _p_escaped(s, l, t): text = t[0] return chr(int(text, 16)) escaped.setParseAction(_p_escaped) value = Combine(OneOrMore(CharsNotIn('*()\\\0') | escaped)) value.setName('value') equal = Literal("=") equal.setParseAction(lambda s, l, t: pureldap.LDAPFilter_equalityMatch) approx = Literal("~=") approx.setParseAction(lambda s, l, t: pureldap.LDAPFilter_approxMatch) greater = Literal(">=")
from pyparsing import Word, Literal, Optional, ZeroOrMore, Suppress, \ Group, Forward, OneOrMore, ParseException, \ CharsNotIn, Combine, StringStart, \ StringEnd, delimitedList import string filter_ = Forward() attr = Word(string.ascii_letters, string.ascii_letters + string.digits + ';-',) attr.leaveWhitespace() attr.setName('attr') hexdigits = Word(string.hexdigits, exact=2) hexdigits.setName('hexdigits') escaped = Suppress(Literal('\\')) + hexdigits escaped.setName('escaped') def _p_escaped(s, l, t): text = t[0] return chr(int(text, 16)) escaped.setParseAction(_p_escaped) value = Combine(OneOrMore(CharsNotIn('*()\\\0') | escaped)) value.setName('value') equal = Literal("=") equal.setParseAction(lambda s, l, t: pureldap.LDAPFilter_equalityMatch) approx = Literal("~=") approx.setParseAction(lambda s, l, t: pureldap.LDAPFilter_approxMatch) greater = Literal(">=")
delimitedList, ) import string filter_ = Forward() attr = Word( string.ascii_letters, string.ascii_letters + string.digits + ";-", ) attr.leaveWhitespace() attr.setName("attr") hexdigits = Word(string.hexdigits, exact=2) hexdigits.setName("hexdigits") escaped = Suppress(Literal("\\")) + hexdigits escaped.setName("escaped") def _p_escaped(s, l, t): text = t[0] return chr(int(text, 16)) escaped.setParseAction(_p_escaped) value = Combine(OneOrMore(CharsNotIn("*()\\\0") | escaped)) value.setName("value") equal = Literal("=") equal.setParseAction(lambda s, l, t: pureldap.LDAPFilter_equalityMatch) approx = Literal("~=") approx.setParseAction(lambda s, l, t: pureldap.LDAPFilter_approxMatch) greater = Literal(">=")
def _create_grammar(): """Create the DBC grammar. """ word = Word(printables.replace(';', '').replace(':', '')) integer = Group(Optional('-') + Word(nums)) positive_integer = Word(nums).setName('positive integer') number = Word(nums + '.Ee-+') colon = Suppress(Literal(':')) scolon = Suppress(Literal(';')) pipe = Suppress(Literal('|')) at = Suppress(Literal('@')) sign = Literal('+') | Literal('-') lp = Suppress(Literal('(')) rp = Suppress(Literal(')')) lb = Suppress(Literal('[')) rb = Suppress(Literal(']')) comma = Suppress(Literal(',')) node = Word(alphas + nums + '_-').setWhitespaceChars(' ') frame_id = Word(nums).setName('frame id') version = Group(Keyword('VERSION') - QuotedString()) version.setName(VERSION) symbol = Word(alphas + '_') + Suppress(LineEnd()) symbols = Group(Keyword('NS_') - colon - Group(ZeroOrMore(symbol))) symbols.setName('NS_') discard = Suppress(Keyword('BS_') - colon).setName('BS_') nodes = Group(Keyword('BU_') - colon - Group(ZeroOrMore(node))) nodes.setName('BU_') signal = Group( Keyword(SIGNAL) - Group(word + Optional(word)) - colon - Group(positive_integer - pipe - positive_integer - at - positive_integer - sign) - Group(lp - number - comma - number - rp) - Group(lb - number - pipe - number - rb) - QuotedString() - Group(delimitedList(node))) signal.setName(SIGNAL) message = Group( Keyword(MESSAGE) - frame_id - word - colon - positive_integer - word - Group(ZeroOrMore(signal))) message.setName(MESSAGE) event = Suppress( Keyword(EVENT) - word - colon - positive_integer - lb - number - pipe - number - rb - QuotedString() - number - number - word - node - scolon) event.setName(EVENT) comment = Group( Keyword(COMMENT) - ((Keyword(SIGNAL) - frame_id - word - QuotedString() - scolon).setName(SIGNAL) | (Keyword(MESSAGE) - frame_id - QuotedString() - scolon).setName(MESSAGE) | (Keyword(EVENT) - word - QuotedString() - scolon).setName(EVENT) | (Keyword(NODES) - word - QuotedString() - scolon).setName(NODES) | (QuotedString() - scolon).setName('QuotedString'))) comment.setName(COMMENT) attribute_definition = Group( Keyword(ATTRIBUTE_DEFINITION) - ((QuotedString()) | (Keyword(SIGNAL) | Keyword(MESSAGE) | Keyword(EVENT) | Keyword(NODES)) + QuotedString()) - word - (scolon | (Group(ZeroOrMore(Group( (comma | Empty()) + QuotedString()))) + scolon) | (Group(ZeroOrMore(number)) + scolon))) attribute_definition.setName(ATTRIBUTE_DEFINITION) attribute_definition_default = Group( Keyword(ATTRIBUTE_DEFINITION_DEFAULT) - QuotedString() - (number | QuotedString()) - scolon) attribute_definition_default.setName(ATTRIBUTE_DEFINITION_DEFAULT) attribute = Group( Keyword(ATTRIBUTE) - QuotedString() - Group( Optional((Keyword(MESSAGE) + frame_id) | (Keyword(SIGNAL) + frame_id + word) | (Keyword(NODES) + word))) - (QuotedString() | number) - scolon) attribute.setName(ATTRIBUTE) choice = Group( Keyword(CHOICE) - Group(Optional(frame_id)) - word - Group(OneOrMore(Group(integer + QuotedString()))) - scolon) choice.setName(CHOICE) value_table = Group( Keyword(VALUE_TABLE) - word - Group(OneOrMore(Group(integer + QuotedString()))) - scolon) value_table.setName(VALUE_TABLE) signal_type = Group( Keyword(SIGNAL_TYPE) - frame_id - word - colon - positive_integer - scolon) signal_type.setName(SIGNAL_TYPE) signal_multiplexer_values = Group( Keyword(SIGNAL_MULTIPLEXER_VALUES) - frame_id - word - word - Group( delimitedList(positive_integer - Suppress('-') - Suppress(positive_integer))) - scolon) signal_multiplexer_values.setName(SIGNAL_MULTIPLEXER_VALUES) message_add_sender = Group( Keyword(MESSAGE_TX_NODE) - frame_id - colon - Group(delimitedList(node)) - scolon) message_add_sender.setName(MESSAGE_TX_NODE) attribute_definition_rel = Group( Keyword(ATTRIBUTE_DEFINITION_REL) - (QuotedString() | (Keyword(NODES_REL) + QuotedString())) - word - (scolon | (Group(ZeroOrMore(Group( (comma | Empty()) + QuotedString()))) + scolon) | (Group(ZeroOrMore(number)) + scolon))) attribute_definition_rel.setName(ATTRIBUTE_DEFINITION_REL) attribute_definition_default_rel = Group( Keyword(ATTRIBUTE_DEFINITION_DEFAULT_REL) - QuotedString() - (number | QuotedString()) - scolon) attribute_definition_default_rel.setName(ATTRIBUTE_DEFINITION_DEFAULT_REL) attribute_rel = Group( Keyword(ATTRIBUTE_REL) - QuotedString() - Keyword(NODES_REL) - word - Keyword(SIGNAL) - frame_id - word - (positive_integer | QuotedString()) - scolon) attribute_rel.setName(ATTRIBUTE_REL) signal_group = Group( Keyword(SIGNAL_GROUP) - frame_id - word - integer - colon - OneOrMore(word) - scolon) signal_group.setName(SIGNAL_GROUP) entry = (message | comment | attribute | choice | attribute_definition | attribute_definition_default | attribute_rel | attribute_definition_rel | attribute_definition_default_rel | signal_group | event | message_add_sender | value_table | signal_type | signal_multiplexer_values | discard | nodes | symbols | version) frame_id.setParseAction(lambda _s, _l, t: int(t[0])) return OneOrMore(entry) + StringEnd()
def __init__(self, basedir: str = '.') -> None: self.__basedir = basedir self.__specifications: Dict[str, Specification] = {} self.__pdus: Dict[str, PDU] = {} self.__refinements: Dict[str, Refinement] = {} # Generic comma = Suppress(Literal(',')) comma.setName('","') semicolon = Suppress(Literal(';')) semicolon.setName('";"') # Comments comment = Regex(r'--.*') # Names identifier = WordStart(alphanums) + Word(alphanums + '_') + WordEnd(alphanums + '_') identifier.setParseAction(verify_identifier) identifier.setName('Identifier') qualified_identifier = Optional(identifier + Literal('.')) - identifier qualified_identifier.setParseAction(lambda t: ''.join(t.asList())) attribute_designator = Keyword('First') | Keyword('Last') | Keyword( 'Length') attribute_reference = identifier + Literal('\'') - attribute_designator attribute_reference.setParseAction(parse_attribute) attribute_reference.setName('Attribute') name = attribute_reference | identifier name.setName('Name') # Literals numeral = Word(nums) + ZeroOrMore(Optional(Word('_')) + Word(nums)) numeral.setParseAction( lambda t: int(''.join(t.asList()).replace('_', ''))) extended_digit = Word(nums + 'ABCDEF') based_numeral = extended_digit + ZeroOrMore( Optional('_') + extended_digit) based_literal = numeral + Literal('#') - based_numeral - Literal('#') based_literal.setParseAction( lambda t: int(t[2].replace('_', ''), int(t[0]))) numeric_literal = based_literal | numeral numeric_literal.setParseAction(lambda t: Number(t[0])) numeric_literal.setName('Number') literal = numeric_literal # Operators mathematical_operator = (Literal('**') | Literal('+') | Literal('-') | Literal('*') | Literal('/')) relational_operator = (Keyword('<=') | Keyword('>=') | Keyword('=') | Keyword('/=') | Keyword('<') | Keyword('>')) logical_operator = Keyword('and') | Keyword('or') # Expressions mathematical_expression = Forward() relation = mathematical_expression + relational_operator - mathematical_expression relation.setParseAction(parse_relation) relation.setName('Relation') logical_expression = infixNotation( relation, [(logical_operator, 2, opAssoc.LEFT, parse_logical_expression)]) logical_expression.setName('LogicalExpression') term = Keyword('null') | literal | name term.setParseAction(parse_term) mathematical_expression << infixNotation( term, [(mathematical_operator, 2, opAssoc.LEFT, parse_mathematical_expression)]) mathematical_expression.setName('MathematicalExpression') # Type Refinement value_constraint = Keyword('if') - logical_expression value_constraint.setParseAction(lambda t: t[1]) type_refinement_definition = ( Keyword('new') - qualified_identifier - Suppress(Literal('(')) - identifier - Suppress(Literal('=>')) - (Keyword('null') | qualified_identifier) - Suppress(Literal(')')) - Optional(value_constraint)) type_refinement_definition.setName('Refinement') # Integer Types size_aspect = Keyword('Size') - Keyword('=>') - mathematical_expression size_aspect.setParseAction(parse_aspect) range_type_aspects = Keyword('with') - size_aspect range_type_aspects.setParseAction(parse_aspects) range_type_definition = (Keyword('range') - mathematical_expression - Suppress(Literal('..')) - mathematical_expression - range_type_aspects) range_type_definition.setName('RangeInteger') modular_type_definition = Keyword('mod') - mathematical_expression modular_type_definition.setName('ModularInteger') integer_type_definition = range_type_definition | modular_type_definition # Enumeration Types enumeration_literal = name positional_enumeration = enumeration_literal + ZeroOrMore( comma - enumeration_literal) positional_enumeration.setParseAction( lambda t: [(k, Number(v)) for v, k in enumerate(t.asList())]) element_value_association = enumeration_literal + Keyword( '=>') - numeric_literal element_value_association.setParseAction(lambda t: (t[0], t[2])) named_enumeration = (element_value_association + ZeroOrMore(comma - element_value_association)) boolean_literal = Keyword('True') | Keyword('False') boolean_literal.setParseAction(lambda t: t[0] == 'True') boolean_aspect_definition = Optional(Keyword('=>') - boolean_literal) boolean_aspect_definition.setParseAction(lambda t: (t if t else ['=>', True])) always_valid_aspect = Literal( 'Always_Valid') - boolean_aspect_definition always_valid_aspect.setParseAction(parse_aspect) enumeration_aspects = Keyword('with') - delimitedList( size_aspect | always_valid_aspect) enumeration_aspects.setParseAction(parse_aspects) enumeration_type_definition = ( Literal('(') - (named_enumeration | positional_enumeration) - Literal(')') - enumeration_aspects) enumeration_type_definition.setName('Enumeration') # Array Type unconstrained_array_definition = Keyword('array of') + name array_type_definition = unconstrained_array_definition array_type_definition.setName('Array') # Message Type first_aspect = Keyword('First') - Keyword( '=>') - mathematical_expression first_aspect.setParseAction(parse_aspect) length_aspect = Keyword('Length') - Keyword( '=>') - mathematical_expression length_aspect.setParseAction(parse_aspect) component_aspects = Keyword('with') - delimitedList(first_aspect | length_aspect) component_aspects.setParseAction(parse_aspects) then = (Keyword('then') - (Keyword('null') | identifier) - Group(Optional(component_aspects)) - Group(Optional(value_constraint))) then.setParseAction(parse_then) then_list = then + ZeroOrMore(comma - then) then_list.setParseAction(lambda t: [t.asList()]) component_list = Forward() message_type_definition = Keyword( 'message') - component_list - Keyword('end message') message_type_definition.setName('Message') component_item = (~Keyword('end') + ~CaselessKeyword('Message') - identifier + Literal(':') - name - Optional(then_list) - semicolon) component_item.setParseAction(lambda t: Component(t[0], t[2], t[3]) if len(t) >= 4 else Component(t[0], t[2])) component_item.setName('Component') null_component_item = Keyword('null') - then - semicolon null_component_item.setParseAction( lambda t: Component(t[0], '', [t[1]])) null_component_item.setName('NullComponent') component_list << (Group( Optional(null_component_item) - component_item - ZeroOrMore(component_item))) component_list.setParseAction(lambda t: t.asList()) # Types type_definition = (enumeration_type_definition | integer_type_definition | message_type_definition | type_refinement_definition | array_type_definition) type_declaration = (Keyword('type') - identifier - Keyword('is') - type_definition - semicolon) type_declaration.setParseAction(parse_type) # Package basic_declaration = type_declaration package_declaration = (Keyword('package') - identifier - Keyword('is') - Group(ZeroOrMore(basic_declaration)) - Keyword('end') - name - semicolon) package_declaration.setParseAction( lambda t: Package(t[1], t[3].asList())) # Context context_item = Keyword('with') - identifier - semicolon context_item.setParseAction(lambda t: t[1]) context_clause = ZeroOrMore(context_item) context_clause.setParseAction(lambda t: Context(t.asList())) # Specification specification = Optional(context_clause + package_declaration) specification.setParseAction(lambda t: Specification(t[0], t[1]) if len(t) == 2 else None) # Grammar self.__grammar = specification + StringEnd() self.__grammar.setParseAction(self.__evaluate_specification) self.__grammar.ignore(comment)