2017-07-27 111 views
0

我創建語法與pyPEG2解析這樣的語句如:pyPEG2給出錯誤的結果

一個喜歡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' 

所以我在做什麼錯誤的方式,文檔描述得很好,但卻無法真正發現我在那裏犯的錯誤。

希望有人可以幫助。提前致謝!!!

回答

1

這裏有兩個問題。

您對分隔符的語法使用Keyword類。這匹配一個默認的「\ 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'