diff --git a/cmake/libucomm.cmake b/cmake/libucomm.cmake index 8cee0a7..07139ee 100644 --- a/cmake/libucomm.cmake +++ b/cmake/libucomm.cmake @@ -5,7 +5,7 @@ macro(libucomm_wrap_msg outfile msg) add_custom_command( OUTPUT ${${outfile}} DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${msg} - COMMAND python ${LIBUCOMM_PARSE_PY} + COMMAND python2 ${LIBUCOMM_PARSE_PY} ${CMAKE_CURRENT_SOURCE_DIR}/${msg} > ${${outfile}} ) diff --git a/libucomm_parse.py b/libucomm_parse.py index a7897c3..bceaaba 100644 --- a/libucomm_parse.py +++ b/libucomm_parse.py @@ -22,6 +22,74 @@ def __init__(self, type): class Identifier: grammar = Word(alphas, alphanums + '_') +class EnumEntry: + grammar = ( + Identifier.grammar("name") + + Optional(Suppress("=") + SkipTo(Literal("}") | Literal(","), include=False)("assignement")) + ) + + def __init__(self, name, assignement=None): + self.name = name + self.assignement = assignement + + def definition(self): + if self.assignement: + return str(self.name) + " = " + str(self.assignement) + "," + else: + return str(self.name) + "," + + @classmethod + def parse(cls, parse_result): + assignement = None + + if parse_result.assignement: + assignement = parse_result.assignement + + return cls(parse_result.name, assignement) +registerParseAction(EnumEntry) + + +class Enum: + grammar = ( + Suppress("enum") + + Optional(Identifier.grammar)("name") + + Suppress("{") + + ( + ZeroOrMore( EnumEntry.grammar + Suppress(Literal(","))) + + Optional(EnumEntry.grammar) + )("entries") + + Suppress("}") + + Suppress(";") + ) + + def __init__(self, name, entries): + self.name = name + self.entries = list(entries) + + def __str__(self): + return self.name + + def definition(self, indent_level = 0): + base_indent = '\t' * indent_level + code = [] + if self.name: + code.append(base_indent + 'enum %s' % self.name) + else: + code.append(base_indent + 'enum') + code += [ + base_indent + '{', + '\n'.join([base_indent + '\t' + e.definition() for e in self.entries]), + base_indent + '};' + ] + + return '\n'.join(code) + + @classmethod + def parse(cls, parse_result): + return cls(parse_result.name, parse_result.entries) +registerParseAction(Enum) + + class Member: grammar = ( Identifier.grammar("type") @@ -126,15 +194,17 @@ class Struct: (Literal('struct') | Literal('msg'))('type') + Identifier.grammar("name") + Suppress('{') + + ZeroOrMore(Enum.grammar)("enums") + ZeroOrMore(Member.grammar)("members") + Suppress('}') + Suppress(';') ) - def __init__(self, type, name, members): + def __init__(self, type, name, members, enums): self.type = type self.name = name self.members = list(members) + self.enums = list(enums) def __str__(self): return self.name @@ -163,6 +233,9 @@ def definition(self): '', ] + if self.enums : + code += [ m.definition(1) for m in self.enums ] + if self.podMembers: code += [ '\tstruct', @@ -262,13 +335,13 @@ def resolveTypes(self, types): @classmethod def parse(cls, parse_result): - return cls(parse_result.type, parse_result.name, parse_result.members) + return cls(parse_result.type, parse_result.name, parse_result.members, parse_result.enums) registerParseAction(Struct) class Grammar: def __init__(self): - self.document = ZeroOrMore(Struct.grammar | Custom.grammar) + self.document = ZeroOrMore(Struct.grammar | Custom.grammar | Enum.grammar) class Parser: def __init__(self, grammar): @@ -288,6 +361,7 @@ def parse(self, string): types = {} + enums = [ s for s in ret if isinstance(s, Enum) ] structs = [ s for s in ret if isinstance(s, Struct) ] custom_areas = [ s for s in ret if isinstance(s, Custom) ] @@ -315,6 +389,10 @@ def parse(self, string): msg_counter = 0 + print + for enum in enums: + print enum.definition() + "\n" + for struct in structs: struct.resolveTypes(types)