我正在使用plyplus来设计一个简单的语法,我一直在努力解决一些奇怪的错误。请记住我是新手。以下是一段重现问题的代码:
from plyplus import Grammar
list_parser = Grammar("""
start: context* ;
context : WORD '{' (rule)* '}' ;
rule: 'require' space_marker ;
space_marker: 'newline'
| 'tab'
| 'space'
;
WORD: '\w+' ;
SPACES: '[ \t\n]+' (%ignore) ;
""", auto_filter_tokens=False)
res = list_parser.parse("test { require tab }")
如果我的输入字符串包含require space
或require newline
,则效果非常好。但是,只要我提供require tab
,就会抛出异常:
Traceback (most recent call last):
File "/Users/bore/Projects/ThesisCode/CssCoco/coco/plytest.py", line 18, in <module>
res = list_parser.parse("test { require tab }")
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/plyplus/plyplus.py", line 584, in parse
return self._grammar.parse(text)
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/plyplus/plyplus.py", line 668, in parse
raise ParseError('\n'.join(self.errors))
plyplus.plyplus.ParseError: Syntax error in input at 'tab' (type WORD) line 1 col 16
具有讽刺意味的是,每次运行代码时我都不会得到这个例外,但是三次都没有。我注意到如果我将语法和输入从tab
更改为ta
,每次运行代码时都会得到相同的异常。此外,如果我将其更改为tabb
,则错误消失。
错误表明tab
被解析为WORD而不是space_marker。但是,tabb
也是一个词。从我的试验和错误看来,plyplus对我作为关键字提供的特定字符串很敏感。我错过了什么吗?任何帮助/提示/评论将受到高度赞赏!
答案 0 :(得分:0)
PlyPlus是PLY的一个实现,其中L和Y代表Lex和Yacc,所以它是 - 更好的是probably worse - 一个LR解析器,它严格自下而上工作。这也意味着'tab'
无法解析为TAB
(或_ANON_X
,或其为令牌生成的任何名称),因为您对WORD
的定义非常慷慨。解决它的唯一方法是使定义更具限制性。例如:
WORD: '\w+' (%unless
TAB: 'tab';
REQ: 'require';
);
我的猜测是它适用于'newline'
和'space'
,因为在某个地方有一个隐式定义的preterminal,其优先级高于WORD
,但是PlyPlus的文档不是确切地说是顶级的,所以我们必须看看PlyPlus的tokeniser的实际实现。