Python 是否可以使用pyparsing解析非平凡的C枚举?

Python 是否可以使用pyparsing解析非平凡的C枚举?,python,pyparsing,Python,Pyparsing,我有一个预处理的C文件,我需要枚举其中一个枚举的成员pyparsing附带了一个简单的示例(examples/cpp_enum_parser.py),但它仅在枚举值为正整数时才起作用。在现实生活中,值可以是负数、十六进制或复杂表达式 我不需要结构化的值,只需要名称 enum hello { minusone=-1, par1 = ((0,5)), par2 = sizeof("a\\")bc};,"), par3 = (')') }; 解析值时,解析器应该跳过所

我有一个预处理的C文件,我需要枚举其中一个枚举的成员
pyparsing
附带了一个简单的示例(
examples/cpp_enum_parser.py
),但它仅在枚举值为正整数时才起作用。在现实生活中,值可以是负数、十六进制或复杂表达式

我不需要结构化的值,只需要名称

enum hello {
    minusone=-1,
    par1 = ((0,5)),
    par2 = sizeof("a\\")bc};,"),
    par3 = (')')
};

解析值时,解析器应该跳过所有内容,直到
[('”,}]
并处理这些字符。对于那些正则表达式或SkipTo可能很有用。对于字符串和字符-QuotedString。对于嵌套括号-Forward(
examples/fourFn.py

更改了原始示例。我不知道为什么它们删除了
enum.ignore(cppStyleComment)
来自原始脚本。将其放回原处

from pyparsing import *
# sample string with enums and other stuff
sample = '''
    stuff before
    enum hello {
        Zero,
        One,
        Two,
        Three,
        Five=5,
        Six,
        Ten=10,
        minusone=-1,
        par1 = ((0,5)),
        par2 = sizeof("a\\")bc};,"),
        par3 = (')')
        };
    in the middle
    enum
        {
        alpha,
        beta,
        gamma = 10 ,
        zeta = 50
        };
    at the end
    '''

# syntax we don't want to see in the final parse tree
LBRACE,RBRACE,EQ,COMMA = map(Suppress,"{}=,")


lpar  = Literal( "(" )
rpar  = Literal( ")" )
anything_topl = Regex(r"[^'\"(,}]+")
anything      = Regex(r"[^'\"()]+")

expr = Forward()
pths_or_str = quotedString | lpar + expr + rpar
expr <<     ZeroOrMore( pths_or_str | anything )
expr_topl = ZeroOrMore( pths_or_str | anything_topl )

_enum = Suppress('enum')
identifier = Word(alphas,alphanums+'_')
expr_topl_text = originalTextFor(expr_topl)
enumValue = Group(identifier('name') + Optional(EQ + expr_topl_text('value')))
enumList = Group(ZeroOrMore(enumValue + COMMA) + Optional(enumValue) )
enum = _enum + Optional(identifier('enum')) + LBRACE + enumList('names') + RBRACE
enum.ignore(cppStyleComment)

# find instances of enums ignoring other syntax
for item,start,stop in enum.scanString(sample):
    for entry in item.names:
        print('%s %s = %s' % (item.enum,entry.name, entry.value))

您必须对可能包含逗号或右大括号但不标记枚举值结尾的术语进行特殊处理

from pyparsing import *

sample = r"""
enum hello {
    minusone=-1,
    par1 = ((0,5)),
    par2 = sizeof("a\")bc};,"),
    par3 = (')')
};
"""

ENUM = Keyword("enum")
LBRACE,RBRACE,COMMA,EQ = map(Suppress, "{},=")
identifier = Word(alphas+"_", alphanums+"_")
identifier.setName("identifier")#.setDebug()

funcCall = identifier + nestedExpr()

enum_value = nestedExpr() | quotedString | funcCall | SkipTo(COMMA | RBRACE)

enum_decl = (ENUM + Optional(identifier, '')("ident") + LBRACE + 
    OneOrMore(identifier + Optional(EQ + enum_value).suppress() + Optional(COMMA))("names") +
    RBRACE
    )

for enum in enum_decl.searchString(sample):
    print enum.ident, ','.join(enum.names)
印刷品

hello minusone,par1,par2,par3

没有注意到nestedExpr。谢谢
hello minusone,par1,par2,par3