0

我用 pyPEG2 创建了语法,用于解析以下语句:

A爱B,B恨A,A恨B,A爱D,B爱C

下面是我的代码:

import pypeg2 as pp


class Person(str):
    grammar = pp.word

class Action(pp.Keyword):
    grammar = pp.Enum(pp.K('loves'), pp.K('hates'))

class Separator(pp.Keyword):
    grammar = pp.Enum(pp.K(','), pp.K('\n'), pp.K('but'), pp.K('and'), pp.K('while'))

relation = Person, Action, Person

class Relations(pp.Namespace):
    grammar = relation, pp.maybe_some(Separator, relation)

但是,当我尝试执行以下操作时:

>>> love = pp.parse('A loves B but B hates A , B loves C, Relations)

我得到:

Traceback (most recent call last):
  File "<pyshell#64>", line 1, in <module>
    love = pp.parse('A loves B but B hates A , B loves C', Relations)
  File "/home/michael/.local/lib/python3.5/site-packages/pypeg2/__init__.py", line 669, in parse
    raise parser.last_error
  File "<string>", line 1
    es B but B hates A , B loves C
                       ^
SyntaxError: expecting Separator
>>> 

如果我更改此声明:

>>> love = pp.parse('A loves B but B hates A and B loves C', Relations)

没有错误,但由于某些原因错过了最后一个块:

>>> pp.compose(love)
'A loves B but B hates A'

那么我做错了什么,文档描述得很好,但无法真正找到我在那里犯的错误。

希望有人可以帮助解决这个问题。提前致谢!!!

4

1 回答 1

1

这里有两个问题。

分隔符的语法使用关键字类。这匹配“\w”的默认正则表达式 - 单词类型字符。(https://fdik.org/pyPEG/grammar_elements.html#keyword

您需要导入 re,并为该类定义自己的正则表达式。此正则表达式应该是您希望允许进入关键字的附加字符,或者至少是一种单词类型。

import re

class Separator(pp.Keyword):
    grammar = pp.Enum(pp.K(','), pp.K('\n'), pp.K('but'), pp.K('and'), pp.K('while'))
    regex = re.compile('[,]|\w+')

这应该有效。

注意 - 我也不确定将换行符作为分隔符是否有效 - 您可能需要深入了解 pypeg2 中单个语法中的多行解析。

另一方面,我认为这与为关系类型使用命名空间有关。

>>> love
Relations([(Symbol('#2024226558144'), 'A'), (Symbol('loves'), 
  Action('loves')), (Symbol('#2024226558384'), 'B'), (Symbol('but'),
  Separator('but')), (Symbol('#2024226558624'), 'B'), (Symbol('hates'),
  Action('hates')), (Symbol('#2024226558864'), 'A'), (Symbol('and'), 
  Separator('and')), (Symbol('#2024226559104'), 'B'),
  (Symbol('#2024226559344'), 'C'), ])

如果您将其设为类型列表,则更有意义 - 因为命名空间应该只有命名的事物,并且不确定为命名空间项具有多个定义意味着什么。

class Relations(pp.Namespace):
  grammar = relation, pp.maybe_some(Separator, relation)

>>> love = pp.parse('A loves B but B hates A and B loves C', Relations)
>>> love
['A', Action('loves'), 'B', Separator('but'), 'B', Action('hates'), 'A', Separator('and'), 'B', Action('loves'), 'C']
>>> pp.compose(love)
'A loves B but B hates A and B loves C'
于 2018-02-03T16:20:57.870 回答