- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
所以我试图用 PLY 构建一个解析器,但它不起作用。它给了我似乎无法解决的错误。我提取了解析器的一小部分并将其放入另一个文件中,用于测试目的:它也不起作用。
这是我似乎无法解决的简化问题:
输入示例
#Trying to parse properties following the patter X1[some text]X2[other text]
#Simplified input used
GM[1]US[hello]
根据我的理解,解析器读取第一个属性(GM[1])并在第二个属性上触发错误。他正在采取尽可能短的减少(我的规则确实允许)并读取单个属性。然后,第二个规则不再遵循,从而触发错误。
所以问题是:你能帮我正确地编写我的规则吗?
解析器.py
#For simplicity, i only give you the rules, and removed operations on the tree.
def p_properties(self,p):
"properties : property property_list"
def p_property_list(self,p):
"property_list : "
" | properties"
def p_property(self,p):
"property : PROPERTY_NAME single_property_content"
def p_single_property_content(self,p):
"single_property_content : OBRACKET TEXT CBRACKET"
起始规则是“属性”。我希望输入属性 (GM[1]) 与规则 property 匹配,第二个属性匹配 property_list。但我认为第一条规则匹配 property 和 property_list (作为 property_list 中的空产生式),它减少为 properties。然后,就不再有可用于读取第二个属性的规则。
这是解析器的输出:
State : 0
Stack : . LexToken(PROPERTY_NAME,'GM',1,0)
Action : Shift and goto state 2
State : 2
Stack : PROPERTY_NAME . LexToken(OBRACKET,'[',1,2)
Action : Shift and goto state 4
State : 4
Stack : PROPERTY_NAME OBRACKET . LexToken(TEXT,'1',1,3)
Action : Shift and goto state 7
State : 7
Stack : PROPERTY_NAME OBRACKET TEXT . LexToken(CBRACKET,']',1,4)
Action : Shift and goto state 8
State : 8
Defaulted state 8: Reduce using 4
Stack : PROPERTY_NAME OBRACKET TEXT CBRACKET . None
Action : Reduce rule [single_property_content -> OBRACKET TEXT CBRACKET] with ['[','1',']'] and goto state 5
Result : <tuple @ 0x7fea37eb4588> (('single_property_content', '1'))
State : 5
Defaulted state 5: Reduce using 3
Stack : PROPERTY_NAME single_property_content . None
Action : Reduce rule [property -> PROPERTY_NAME single_property_content] with ['GM',<tuple @ 0x7fea37eb4588>] and goto state 3
Result : <tuple @ 0x7fea3964f798> (('property', 'GM', ('single_property_con ...)
State : 3
Defaulted state 3: Reduce using 2
Stack : property . None
Action : Reduce rule [property_list -> <empty>] with [] and goto state 6
Result : <NoneType @ 0xa3f020> (None)
State : 6
Defaulted state 6: Reduce using 1
Stack : property property_list . None
Action : Reduce rule [properties -> property property_list] with [<tuple @ 0x7fea3964f798>,None] and goto state 1
Result : <tuple @ 0x7fea3964f678> (('properties', ('property', 'GM', ('sing ...)
State : 1
Stack : properties . LexToken(PROPERTY_NAME,'US',1,5)
ERROR: Error : properties . LexToken(PROPERTY_NAME,'US',1,5)
Error while parsing : LexToken(PROPERTY_NAME,'US',1,5)
State : 1
Stack : properties . error
ERROR: Error : properties . error
State : 0
Stack : . error
ERROR: Error : . error
State : 0
Stack : . LexToken(OBRACKET,'[',1,7)
ERROR: Error : . LexToken(OBRACKET,'[',1,7)
State : 0
Stack : . LexToken(TEXT,'hello',1,8)
ERROR: Error : . LexToken(TEXT,'hello',1,8)
State : 0
Stack : . LexToken(CBRACKET,']',1,13)
ERROR: Error : . LexToken(CBRACKET,']',1,13)
State : 0
Stack : . $end
ERROR: Error : . $end
None
我用 15 种不同的方式修改了这些规则(右递归、左递归),但没有效果。你们能告诉我我做错了什么吗?
编辑在实现解决方案时遇到一些麻烦(仅当我解析 2 个元素但解析更多创建的错误时才有效),感谢 @rici 的帮助,我设法使其工作。
解决方案
def p_properties(self,p):
"""
properties : property_list property
"""
p[0] = ('properties',p[1], p[2])
def p_property_list(self,p):
"""
property_list : property_list property
|
"""
if(len(p)==3):
p[0] = ('property_list',p[1],p[2])
def p_property(self,p):
"""
property : PROPERTY_NAME property_content_list
"""
p[0] = ('property', p[1], p[2])
输入
GM[1]AP[hello]AW[world]C[1.this is a comment]C[2.this is a comment]C[3.this is a comment]
TM[50]WR[alalala]GM[will it fail?]GM[should succeed]
结果
('properties', ('property_list', ('property_list', ('property_list',
('property_list', ('property_list', ('property_list',
('property_list',('property_list', ('property_list', None,
('property', 'GM', ('property_content', '1'))),
('property', 'AP', ('property_content','hello'))),
('property', 'AW', ('property_content', 'world'))),
('property', 'C', ('property_content', '1.this is a comment'))),
('property', 'C', ('property_content', '2.this is a comment'))),
('property', 'C', ('property_content', '3.this is a comment'))),
('property', 'TM', ('property_content', '50'))), ('property', 'WR',
('property_content', 'alalala'))), ('property', 'GM',
('property_content','will it fail?'))),
('property', 'GM', ('property_content', 'should succeed')))
感谢您的帮助。
卢伊克。
最佳答案
Ply 解析器的产生式包含在文档字符串中,它是函数开头的第一个字符串文字(如果有)。
因此,p_property_list
的文档字符串为 property_list:
。 (您可以通过查看 p_property_list.__doc__ 来确认这一点。)这就是 Ply 看到的全部内容。如果您想为单个函数提供多个产生式,请使用单个多行字符串文字,这就是为什么您通常将原始字符串文字视为文档字符串的原因:
def p_property_list(self, p):
"""property_list:
| property_list property
"""
# ...
但是,在这种情况下使用两个不同的函数是很常见的。见下文。
<小时/>除非必要,否则不要使用右递归。正确的语法是:
property_list: property
| property_list property
property: PROPERTY_NAME single_property_content
如果您愿意,您可以调用第一个生产 properties
,但您不需要两个不同的非终端。 (您可能也不需要 single_property_content
,但这取决于您的语法的其余部分。)
在 Ply 中,无需将归约函数与非终结符对齐。对于归约操作不同的不同替代方案使用不同的函数是很常见的,并且您通常可以为不同的非终结符组合类似的产生式。举个简单的例子:
# This function can be used as the base case of any list non-terminal
# whose semantic value is a list (and whose base case is not empty)
def p_list_base(self, p):
"""property_list: property
function_list: function
"""
p[0] = [p[1]]
# This function can be used as the recursion of any list non-terminal
# whose semantic value is a list.
def p_list_recur(self, p):
"""property_list: property_list property
function_list: function_list function
"""
p[1].append(p[2])
p[0] = p[1]
关于python - PLY : Parsing error. 规则意外匹配空标记集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46153460/
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许在 Stack Overflow 上提出有关通用计算硬件和软件的问题。您可以编辑问题,使其成为
当我尝试在 db2 中创建表时,它抛出以下错误 $ db2 CREATE TABLE employee(emp_id INT NOT NULL, emp_name VARCHAR(100)) sh:
我有: while (i < l) { if (one === two) { continue; } i++; } 但是 JSLint 说: Problem at line 1 chara
所以我有这个代码: char inputs[10] = ""; int numInputs = 0; while (numInputs < 10){ char c; printf("E
var ninja = { name: 'Ninja', say: function () { return 'I am a ' + this.name; }
我收到一个我不明白的错误,请注意,我是编码新手,所以这可能是一个简单的错误。 #include using namespace std; int main() { //Initialise Fahr
我正在使用 javascript 和 react,由于某种原因,我收到了一个奇怪的 token 错误。 这是发生错误的代码: renderNavBar() { if (!this.us
Closed. This question is off-topic。它当前不接受答案。
由于某种我无法解释的原因,编译器正在输出一个错误,指出它发现了一个意外的#else 标记。 这发生在文件的开头: #if defined( _USING_MFC ) #include "stda
这个问题不太可能帮助任何 future 的访问者;它只与一个小的地理区域、一个特定的时间点或一个非常狭窄的情况有关,这些情况并不普遍适用于互联网的全局受众。为了帮助使这个问题更广泛地适用,visit
这个问题在这里已经有了答案: Difference between sh and Bash (11 个答案) 关闭 2 年前。 我正在编写一个简单的 bash 脚本,我在 XX `(' unexpe
关闭。这个问题是not reproducible or was caused by typos .它目前不接受答案。 此问题是由拼写错误或无法再重现的问题引起的。虽然类似的问题可能是 on-topic
我在 Windows 7 上编写了一个脚本,它不断给我一个错误“(此时出乎意料。”对于以下代码 if %vardns%=="NODNS" ( netsh interface ipv4 set ad
我正在尝试使用xmlstarlet(使用xpath)解析XML文件,但是出现语法错误,并且我不知道如何更正我的代码。 这是我的脚本: #!/bin/bash if [ $1=="author" ];
以下脚本旨在在目录中的所有文件上运行程序“senna”,并将每个文件的输出(保留输入文件名)写入另一个目录 for file in ./Data/in/*; do ./senna -iobta
我从 challengers.coffee 运行此代码,并收到错误 ActionView::Template::Error (SyntaxError: [stdin]:3:31:unexpected
我在 config.db.database; 行中有语法错误(意外的标记“.”)。这是我在文件中的代码 const config = require('../config/config') const
这一定很明显,但是我无法使它正常工作。我正在尝试传输应该用于构建$ classKey的对象,这反过来又导致删除所需的软件(amd64或i386)。好吧,这里的代码: $name = @("softwa
我正在使用 1.3.7 版学习 Grails,但我一直无缘无故地遇到以下语法错误: unexpected token: mapping @ line x, column y. 有一次,我通过运行“gr
我正在尝试找出这段Pascal代码的问题 function Factorial(n: integer): integer; begin if n = 0 then Result := 1
我是一名优秀的程序员,十分优秀!