带选项的Pyparsing

2024-05-29 01:37:13 发布

您现在位置:Python中文网/ 问答频道 /正文

我有这样的东西

IDENTIFIER = Word(alphas + '_', alphanums + '_') #words
GENERIC_TYPE = Regex('[a-zA-Z_]+[a-zA-Z0-9_]*(\<[a-zA-Z0-9_]+\>)?') #List<string> or int
AMF = Keyword('public') | Keyword('private') | Keyword('protected') #method modifier
SFMF = Optional(Keyword('static')) & Optional(Keyword('final')) #static and final modifiers

对于本例:

^{pr2}$

它打印:['Method'],但是如果我添加Optional(GENERIC_TYPE)

res = (Optional(AMF) +
       SFMF +
       Optional(GENERIC_TYPE) +
       IDENTIFIER).parseString(text)
print(res)

它为text='int Method'打印['int', 'Method'],但为'final Method'(或仅'Method')引发异常:

pyparsing.ParseException: Expected W:(abcd...,abcd...) (at char 12), (line:1, col:13)

看起来pyparsing看不到可选的东西,因为如果GENERIC_TYPE是可选的(就像前面的很多东西一样),它应该更进一步地解析标识符部分。在

更新:

问题似乎出在解析的逻辑上。如果有两个相等的模式,其中一个是可选的,那么解析器不会检查它是否与第二个模式有关。例如:

m = Optional('M') + Literal('M')
m.parseString('M')

解析器将“M”与第一部分匹配,然后忽略非可选的文本部分。在

所以现在的问题是,我能解析它,使它与第二个匹配吗。它可能不在字符串或行的末尾,所以我不能使用它。在


Tags: typestaticreskeywordoptionalmethodgenericfinal
1条回答
网友
1楼 · 发布于 2024-05-29 01:37:13

我会说,“通用的类型后面必须有一个标识符”。因此,要解决语法问题,请将res重写为:

res = (Optional(AMF) +
       SFMF +
       Optional(GENERIC_TYPE + FollowedBy(IDENTIFIER)) +
       IDENTIFIER).parseString(text)

你也可以这样写:

^{pr2}$

Pyparsing不像regex那样做任何前瞻性的工作,你必须把它显式地包含在语法定义中。在

另外,由于IDENTIFIER将匹配任何字符串,您可能需要定义一个类似“keyword”的表达式来匹配所有语言关键字,然后将IDENTIFIER定义为:

keyword = MatchFirst(map(Keyword,"public private protected static final".split()))
IDENTIFIER = ~keyword + Word(alphas + '_', alphanums + '_')

最后,您可能希望泛型类型不仅仅处理简单的container<type>定义,比如Map<String,String>Map<String,List<String>>甚至{}。在

这将解析所有这些:

GENERIC_TYPE = Group(IDENTIFIER + nestedExpr('<', '>', content=delimitedList(IDENTIFIER)))

相关问题 更多 >

    热门问题