运算符的 Pyparsing 问题

发布于 2024-10-18 05:08:23 字数 675 浏览 1 评论 0原文

我用 pyparsing 做了语法,但遇到了问题。 该语法尝试解析搜索查询(使用运算符优先级、括号等),并且我需要空格来像 and 运算符一样工作。

例如,这工作正常:

(word and word) or word

但这失败:

(word word) or word

我希望第二个查询像第一个查询一样工作。

我的实际语法是:

WWORD = printables.replace("(", "").replace(")", "")
QUOTED = quotedString.setParseAction(removeQuotes)

OAND = CaselessLiteral("and")
OOR = CaselessLiteral("or")
ONOT = "-"

TERM = (QUOTED | WWORD)

EXPRESSION = operatorPrecedence(TERM,
    [
        (ONOT, 1, opAssoc.RIGHT),
        (OAND, 2, opAssoc.LEFT),
        (OOR, 2, opAssoc.LEFT)
    ])

STRING = OneOrMore(EXPRESSION) + StringEnd()

I did a grammar with pyparsing, and I have a problem.
The grammar tries to parse a search query (with operator precedence, parenthesis, etc), and I need for spaces to work like the and operator.

For example, this works fine:

(word and word) or word

But this fails:

(word word) or word

And I want the second query to works like the first one.

My actual grammar is:

WWORD = printables.replace("(", "").replace(")", "")
QUOTED = quotedString.setParseAction(removeQuotes)

OAND = CaselessLiteral("and")
OOR = CaselessLiteral("or")
ONOT = "-"

TERM = (QUOTED | WWORD)

EXPRESSION = operatorPrecedence(TERM,
    [
        (ONOT, 1, opAssoc.RIGHT),
        (OAND, 2, opAssoc.LEFT),
        (OOR, 2, opAssoc.LEFT)
    ])

STRING = OneOrMore(EXPRESSION) + StringEnd()

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

还在原地等你 2024-10-25 05:08:23

解决问题的一种方法是将 AND 定义为可选运算符。如果您这样做,则必须格外小心,确保“and”和“or”等真正的关键字不会被误解为搜索词。此外,使用Optional,您可以添加默认字符串,这样即使原始搜索查询中缺少“and”,您的解析文本也会为您插入它(以便于解析后处理)。

from pyparsing import *

QUOTED = quotedString.setParseAction(removeQuotes)  
OAND = CaselessLiteral("and") 
OOR = CaselessLiteral("or") 
ONOT = Literal("-")
WWORD = ~OAND + ~OOR + ~ONOT + Word(printables.replace("(", "").replace(")", ""))
TERM = (QUOTED | WWORD)  
EXPRESSION = operatorPrecedence(TERM,
    [
    (ONOT, 1, opAssoc.RIGHT),
    (Optional(OAND,default="and"), 2, opAssoc.LEFT),
    (OOR, 2, opAssoc.LEFT)
    ])

STRING = OneOrMore(EXPRESSION) + StringEnd()

tests = """\
word and ward or wird
word werd or wurd""".splitlines()

for t in tests:
    print STRING.parseString(t)

给出:

[[['word', 'and', 'ward'], 'or', 'wird']]
[[['word', 'and', 'werd'], 'or', 'wurd']]

One way to address your problem is to define AND as an Optional operator. If you do this, you'll have to take extra care that real keywords like 'and' and 'or' aren't misinterpreted as search words. Also, with Optional, you can add a default string, so that even if the "and" is missing in the original search query, your parsed text will insert it for you (for easier post-parse processing).

from pyparsing import *

QUOTED = quotedString.setParseAction(removeQuotes)  
OAND = CaselessLiteral("and") 
OOR = CaselessLiteral("or") 
ONOT = Literal("-")
WWORD = ~OAND + ~OOR + ~ONOT + Word(printables.replace("(", "").replace(")", ""))
TERM = (QUOTED | WWORD)  
EXPRESSION = operatorPrecedence(TERM,
    [
    (ONOT, 1, opAssoc.RIGHT),
    (Optional(OAND,default="and"), 2, opAssoc.LEFT),
    (OOR, 2, opAssoc.LEFT)
    ])

STRING = OneOrMore(EXPRESSION) + StringEnd()

tests = """\
word and ward or wird
word werd or wurd""".splitlines()

for t in tests:
    print STRING.parseString(t)

Gives:

[[['word', 'and', 'ward'], 'or', 'wird']]
[[['word', 'and', 'werd'], 'or', 'wurd']]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文