def test_grammar_tag(self): grammar = Grammar( Tag( 'a', Tag('b', choice(Tag('c', 'WORD'), Tag('d', Optional('NUMBER')))))) datas = [([('WORD', 'bar')], ('a', ('b', ('c', 'bar')))), ([('NUMBER', '1')], ('a', ('b', ('d', ['1'])))), ([], ('a', ('b', ('d', []))))] self.parse_and_assert_tree(grammar, datas)
def test_grammar_choice_dict(self): number = Forward() number <<= Sequence('NUMBER') grammar = Grammar(ChoiceDict(number, Tag('foo', Sequence('WORD')), ChoiceDict('BAR'), 'FIE')) datas = [ ( [('WORD', 'm')], ('foo', ['m']) ), ( [('NUMBER', '5')], ['5'] ), ( [('BAR', 'foo')], 'foo' ), ( [('FIE', 'fum')], 'fum' ) ] self.parse_and_assert_tree(grammar, datas)
def test_grammar_tag_mismatch(self): grammar = Grammar(Tag('a', 'WORD')) datas = [ ( [('NUMBER', 'bar')], 1 ) ] self.parse_and_assert_mismatch(grammar, datas)
def grammar(self): ident = choice('IDENT', *self.KEYWORDS) full_ident = DelimitedList(ident, '.') empty_statement = ';' message_type = Sequence(Optional('.'), full_ident) constant = choice(Tag('bool', choice('true', 'false')), Tag('ident', full_ident), Tag('string', 'STRING'), Tag('integer', 'INT')) option_name = Sequence(choice(ident, Sequence('(', full_ident, ')')), ZeroOrMore(Sequence('.', ident))) options = Optional( Sequence('[', DelimitedList(Sequence(option_name, '=', constant)), ']')) # Import. import_ = Sequence('import', Optional(choice('weak', 'public')), 'STRING') # Package. package = Sequence('package', full_ident, ';') # Option. option = Sequence('option', option_name, '=', constant, ';') # Enum. enum_field = Sequence(ident, '=', 'INT', options, ';') enum = Sequence('enum', ident, '{', ZeroOrMore(choice(enum_field, empty_statement)), '}') # Oneof. oneof_field = Sequence(message_type, ident, '=', 'INT', ';') oneof = Sequence('oneof', ident, '{', ZeroOrMore(choice(oneof_field, empty_statement)), '}') # Map. map_field = Sequence('map', '<', ident, ',', message_type, '>', ident, '=', 'INT', options, ';') # Reserved. field_number_range = Sequence( 'INT', Optional(Sequence('to', choice('INT', 'max')))) reserved = Sequence( 'reserved', choice(DelimitedList(field_number_range), DelimitedList('STRING'))) # Message. field = Sequence(Optional('repeated'), message_type, ident, '=', 'INT', options, ';') message = Forward() message <<= Sequence( 'message', ident, '{', ZeroOrMore( choice(Tag('field', field), enum, message, oneof, map_field, reserved, empty_statement)), '}') # Service. rpc_name = ident rpc = Sequence('rpc', rpc_name, '(', Optional('stream'), message_type, ')', 'returns', '(', Optional('stream'), message_type, ')', choice(Sequence('{', ZeroOrMore(option), '}'), ';')) service = Sequence('service', ident, '{', ZeroOrMore(choice(option, rpc, empty_statement)), '}') # Proto3-file. top_level_def = choice(message, enum, service) syntax = Sequence('syntax', '=', 'PROTO3', ';') proto = Sequence( syntax, ZeroOrMoreDict( choice(import_, package, option, top_level_def, empty_statement))) return proto
def grammar(self): nls = OneOrMore('NL') any_until_keyword = AnyUntil(Sequence('NL', choice(*KEYWORDS))) any_until_nl = AnyUntil(choice('NL', '__EOF__')) sub_parameter = Tag('SubParameter', Sequence(nls, 'WORD', 'WS', 'WORD')) sub_parameter_typ_min_max = Tag( 'SubParameterTypMinMax', Sequence(nls, 'WORD', 'WS', 'WORD', 'WS', 'WORD', 'WS', 'WORD')) numerical_sub_parameter = Tag( 'NumericalSubParameter', Sequence(nls, 'WORD', Optional('WS'), 'EQ', Optional('WS'), 'WORD')) ibis_ver = Sequence(Optional(nls), '__SOF__', Optional(nls), '[ibis ver]', 'WS', 'WORD') comment_char = Sequence('[comment char]') file_name = Sequence('[file name]', 'WS', 'WORD') file_rev = Sequence('[file rev]', 'WS', 'WORD') date = Sequence('[date]', any_until_nl) source = Sequence('[source]', any_until_keyword) notes = Sequence('[notes]', any_until_keyword) disclaimer = Sequence('[disclaimer]', any_until_keyword) copyright_ = Sequence('[copyright]', any_until_keyword) component = Sequence('[component]', any_until_nl, ZeroOrMore(Sequence(nls, 'WORD', 'WS', 'WORD'))) manufacturer = Sequence('[manufacturer]', any_until_nl) package = Sequence( '[package]', ZeroOrMore( Sequence(nls, 'WORD', 'WS', 'WORD', 'WS', 'WORD', 'WS', 'WORD'))) pin = Sequence( '[pin]', 'WS', 'WORD', 'WS', 'WORD', 'WS', 'WORD', 'WS', 'WORD', 'WS', 'WORD', ZeroOrMore( choice( Tag( 'All', Sequence(nls, Optional('WS'), 'WORD', 'WS', 'WORD', 'WS', 'WORD', 'WS', 'WORD', 'WS', 'WORD', 'WS', 'WORD')), Tag( 'Triple', Sequence(nls, Optional('WS'), 'WORD', 'WS', 'WORD', 'WS', 'WORD'))))) diff_pin = Sequence( '[diff pin]', 'WS', 'WORD', 'WS', 'WORD', 'WS', 'WORD', 'WS', 'WORD', 'WS', 'WORD', ZeroOrMore( Sequence(nls, 'WORD', 'WS', 'WORD', 'WS', 'WORD', 'WS', 'WORD', 'WS', 'WORD', 'WS', 'WORD'))) series_switch_groups = Sequence( '[series switch groups]', ZeroOrMore(Sequence(nls, any_until_nl))) model_selector = Sequence( '[model selector]', 'WS', 'WORD', ZeroOrMore(Sequence(nls, 'WORD', any_until_nl))) model = Sequence( '[model]', 'WS', 'WORD', ZeroOrMore( choice( Tag( 'Quad', Sequence(nls, 'WORD', 'WS', 'WORD', 'WS', 'WORD', 'WS', 'WORD')), sub_parameter, numerical_sub_parameter))) add_submodel = Sequence( '[add submodel]', ZeroOrMore(Sequence(nls, 'WORD', 'WS', 'WORD'))) temperature_range = Sequence('[temperature range]', 'WS', 'WORD', 'WS', 'WORD', 'WS', 'WORD') voltage_range = Sequence('[voltage range]', 'WS', 'WORD', 'WS', 'WORD', 'WS', 'WORD') pullup_reference = Sequence('[pullup reference]', 'WS', 'WORD', 'WS', 'WORD', 'WS', 'WORD') pulldown_reference = Sequence('[pulldown reference]', 'WS', 'WORD', 'WS', 'WORD', 'WS', 'WORD') quad_table = ZeroOrMore( Sequence(nls, Optional('WS'), 'WORD', 'WS', 'WORD', 'WS', 'WORD', 'WS', 'WORD')) gnd_clamp = Sequence('[gnd clamp]', quad_table) power_clamp = Sequence('[power clamp]', quad_table) pullup = Sequence('[pullup]', quad_table) pulldown = Sequence('[pulldown]', quad_table) ramp = Sequence( '[ramp]', ZeroOrMore( choice(numerical_sub_parameter, sub_parameter_typ_min_max))) waveform = ZeroOrMore( choice( Tag( 'TableEntry', Sequence(nls, Optional('WS'), 'WORD', 'WS', 'WORD', 'WS', 'WORD', 'WS', 'WORD')), numerical_sub_parameter)) falling_waveform = Sequence('[falling waveform]', waveform) rising_waveform = Sequence('[rising waveform]', waveform) submodel = Sequence('[submodel]', 'WS', 'WORD', OneOrMore(sub_parameter)) submodel_spec = Sequence('[submodel spec]', OneOrMore(sub_parameter_typ_min_max)) unknown_keyword = Sequence('KEYWORD', any_until_keyword) end = Sequence('[end]') ibis_file = Sequence( ibis_ver, ZeroOrMore( Sequence( nls, choice(comment_char, file_name, file_rev, date, source, notes, disclaimer, copyright_, component, manufacturer, package, pin, diff_pin, series_switch_groups, model_selector, model, add_submodel, temperature_range, voltage_range, pullup_reference, pulldown_reference, gnd_clamp, power_clamp, pullup, pulldown, ramp, falling_waveform, rising_waveform, submodel, submodel_spec, unknown_keyword, end)))) return ibis_file