python - pypeg2 - 可以使用 peg 语法解析此表达式吗?

标签 python regex parsing grammar peg

我需要根据以下规则解析表达式:

  1. 表达式可以包含表示为 name:value 的过滤器对象
  2. 一个表达式可以包含一个字符串表达式
  3. 表达式可以包含 bool 值 OR,AND
  4. 里面的都可以引用

所以一个典型的表达式看起来像

filter1:45 Hello World 过滤器:5454

filter1:45 'hello world' 过滤器:5454

Hello World

'hello world' 或 filter:43


这是我到目前为止尝试过的:

class BooleanLiteral(Keyword):
    grammar = Enum(K("OR"), K("AND"))

class LineFilter(Namespace):
    grammar = flag('inverted', "-"), name(), ":", attr('value', word)

class LineExpression(List):
    grammar = csl(LineFilter, separator=blank)

有了这个语法,我可以像这样解析字符串

filter2:32 filter1:3243

根据我的理解,我可以为 csl 函数提供一个对象列表,并且语法需要按该顺序排列。但是,如果我想解析像

这样的对象怎么办?

filter34:43 你好 filter32:3232

filter34:43 或 filter32:3232

我怎么能说一个表达式中有多种类型的对象(过滤器、表达式、 bool 值)?用 peg 可以吗?

最佳答案

根据您在问题和评论中的规范,我认为您的代码很接近 - 但您不需要 csl。我把我认为你想要的代码放在下面(它可能不是最优雅的实现,但我认为它是合理的)。您必须避免 BooleanLiteralStringLiteral 的子集这一潜在问题。这意味着你不能让 LineExpression

grammar = maybe_some([LineFilter,StringLiteral]), optional(BooleanLiteral)

我认为,结果是根据您的规范具有正确类型的对象列表。我认为需要强调的关键一点是,您可以将备选方案作为 python list(即 [LineFilter,StringLiteral] 表示 LineFilter 或一个 StringLiteral)。 PEG 解析器将按照它们出现的顺序尝试它们,即它会尝试匹配第一个,只有在失败时才会尝试第二个,依此类推。

from pypeg2 import *

class BooleanLiteral(Keyword):
    # Need to alter keyword regex to allow for quoted literal keywords
    K.regex=re.compile(r'"*\w+"*') 
    grammar = Enum(K('OR'), K('AND'),K(r'"OR"'), K(r'"AND"')) 

class LineFilter(Namespace):
    grammar = flag('inverted', "-"), name(), ":", attr('value', word)

class StringLiteral(str):
     quoted_string = re.compile(r'"[^"]*"')
     grammar = [word, quoted_string]

class LineExpression(List):
    grammar = maybe_some([(LineFilter,BooleanLiteral),
                          (StringLiteral,BooleanLiteral),
                          LineFilter,
                          StringLiteral])

test_string = ('filter34:43 "My oh my!!" Hello OR '
               'filter32:3232 "AND" "Goodbye cruel world"')

k = parse(test_string,LineExpression)

print('Input:')
print(test_string)
print('Parsed output:')
print('==============')
for component in k:
    print(component,type(component))

输出

Input:
filter34:43 "My oh my!!" Hello OR filter32:3232 "AND" "Goodbye cruel world"
Parsed output:
==============
LineFilter([], name=Symbol('filter34')) <class '__main__.LineFilter'>
"My oh my!!" <class '__main__.StringLiteral'>
Hello <class '__main__.StringLiteral'>
OR <class '__main__.BooleanLiteral'>
LineFilter([], name=Symbol('filter32')) <class '__main__.LineFilter'>
"AND" <class '__main__.BooleanLiteral'>
"Goodbye cruel world" <class '__main__.StringLiteral'>

关于python - pypeg2 - 可以使用 peg 语法解析此表达式吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33936124/

相关文章:

python - 如何将十六进制 ASCII 字符串转换为有符号整数

javascript - Django 将 Python 对象从 View 传递到模板中的 Javascript 脚本

javascript - 为什么 RegExp 版本在/patt/version 工作时不工作? (JavaScript)

Java string.replaceAll() 无法将\R 识别为字符类的一部分

javascript - 如何解析 GWT 中的日期?

java - 正则表达式:复数

python - 绑定(bind)Python的OpenCV中,为什么不调用NumPy函数就可以使用?

Python 日期字符串 mm/dd/yyyy 转日期时间

MySQL 电子邮件地址搜索列

python - 从txt解析IP地址