- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试使用PLY lex / yacc解析PDF,而我却遇到了有关yacc解析规则的问题,该规则控制NUMBER
标记,数组和indirect_references。
相关资料来源:
def p_value_list(t):
r'''value_list : value_list value
| value'''
if t.slice[0] == 'item_list':
t[0] = {'type':'value_list', 'children' : t[0]['children'] + [t[1]] }
else:
t[0] = {'type':'value_list', 'children' : [t[1]] }
pass
def p_value(t):
r'''value : dictionary
| array
| indirect_reference
| NUMBER
| HEX
| STREAM
| TEXT
| BOOL
| empty'''
t[0] = t[1]
pass
def p_indirect_reference(t):
r'''indirect_reference : NUMBER NUMBER KEY_R'''
t[0] = {'type':'indirect_reference', 'children' : [t[1], t[2]] }
pass
def p_array(t):
r'''array : LBRACKET value_list RBRACKET'''
t[0] = {'type':'array', 'children' : t[2] }
pass
NUMBERS
的规则不明确(您是否有列表
NUMBER NUMBER
或间接引用
NUMBER NUMBER KEY_R
)-解析简单数组
NUMBER
时,我得到的错误范围来自意外的
[0 0 0]
标记
ERROR: Error : obj_list NUMBER NUMBER OBJ LTLT key_value_list ID LBRACKET NUMBER NUMBER . LexToken(NUMBER,'0',1,166273)
ERROR: Error : obj_list NUMBER NUMBER OBJ LTLT key_value_list ID LBRACKET NUMBER NUMBER . LexToken(RBRACKET,']',1,88)
KEY_R
标记组成的数组时,它期待一个
NUMBER
标记:
[ 486 173]
最佳答案
这并不是真正的模棱两可;语法是完全明确的。但是,它不是LR(1),并且LR(1)解析器无法确定是对整数进行移位还是缩小(如果后面跟随另一个整数)。 (语法为LR(2),因为第二个下一个标记足以确定;如果为R
,则该整数是间接引用中的第一个标记,应进行移位。
解决该问题要复杂得多。从理论上讲,您可以将任何LR(2)语法转换为LR(1)语法,但是转换很麻烦,而且我不知道执行该操作的任何自动化工具。基本思想是扩展生产,以避免在遇到足够的上下文之前无需缩减,然后根据需要修复解析树。
(有关此问题的其他可能解决方案,请参见下文。显示的最后一个选项是我个人的最爱。)
这是LR(2)→LR(1)技术的说明;您可以看到NUMBER
令牌是如何简单累积的,直到知道其处置为止:
value_not_number
: dictionary
| array
| HEX
| STREAM
| TEXT
| BOOL
| empty
value_list
: value_list_ends_non_number
| value_list_ends_one_number
| value_list_ends_two_numbers
| value_list_ends_indref
|
value_list_ends_one_number
: value_list_ends_non_number NUMBER
value_list_ends_two_numbers
: value_list_ends_non_number NUMBER NUMBER
| value_list_ends_two_numbers NUMBER
value_list_ends_indref
: value_list_ends_two_numbers 'R'
value_list_ends_non_number
: value_list value_not_number
array : '[' value_list ']'
0 0 R
解析为
value_list_ends_two_numbers
,后跟
R
。为了检索真实的分析树,
value_list_ends_indref
的归约操作需要从其第一个子代中窃取最后两个数字,使用它们来制造间接引用对象,然后将其添加到第一个子代的末尾。因此带有动作的PLY语法可能如下所示:
def p_unit_productions(t):
r'''value_not_number
: dictionary
| array
| HEX
| STREAM
| TEXT
| BOOL
value_list
: value_list_ends_non_number
| value_list_ends_one_number
| value_list_ends_two_numbers
| value_list_ends_indref'''
t[0] = t[1]
def p_value_list_empty(t):
r'''value_list:'''
t[0] = []
def p_value_list_push(t):
r'''value_list_ends_one_number
: value_list_ends_non_number NUMBER
value_list_ends_two_numbers
: value_list_ends_two_numbers NUMBER
value_list_ends_non_number
: value_list value_not_number'''
t[0] = t[1]
t[0].append(t[2])
def p_value_list_push2(t):
r'''value_list_ends_two_numbers
: value_list_ends_non_number NUMBER NUMBER'''
t[0] = t[1]
t[0].append(t[2])
t[0].append(t[3])
def p_indirect_reference(t):
r'''value_list_ends_indref
: value_list_ends_two_numbers 'R' '''
t[0] = t[1]
gen = t[0].pop()
obj = t[0].pop()
t[0].append({'type': 'indirect_reference',
'children': [obj, gen] })
def p_array(t):
r'''array : '[' value_list ']' '''
t[0] = {'type':'array', 'children' : t[2] }
value_list
对象类型(在我看来这是不必要的)。
value: empty
是空的非终结符,所以删除了
empty
。这将导致真正的歧义,因为您不知道在两个非终端之间找到了多少个空字符串。
bison
本身使用此技术来区分作品的左侧和右侧的符号。 (您可以在看到或看不到符号后的冒号时区分开来,但是您必须知道符号本身何时是第一个前瞻。)
R
和以
R
开头的标识符令牌,并且您可能有忽略空白的规则。这些都不会对您识别间接引用的规则有所帮助;您需要显式匹配空白,并且需要显式验证
R
之后的内容不能形成更长的标识符。这并不是很复杂,但是也不是简单的。您需要做一些工作来创建适当的测试范围。
bison
确实具有GLR选项,将野牛解析器包装到python模块中相对简单(如果很重要的话,它可能比PLY解析器更快)。
]
令牌通过弹出堆栈直到找到
[
并将弹出的元素放入新创建的数组对象中来创建数组,然后将其压入堆栈。
R
令牌的操作是将两件事从栈顶弹出。检查它们是数字;然后使用这两个数字构造一个间接引用对象,然后将其推入堆栈。
关于python - PLY/YACC解析PDF上的冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38627699/
在 ms sql 2008 中编写一些存储过程时,当我输入一些变量名称时,我注意到 PLI 被突出显示为关键字。 有谁知道 PLI 的用途是什么? 最佳答案 您可以在 MSDN 上查看此类信息: 请参
我想使用 plyr 的并行功能函数内封装。 我原以为导出在函数体内创建的对象的正确方法(在本例中,对象是 df_2 )如下 # rm(list=ls()) library(plyr) library(
我是 3D 重建的新手,我有点云。我把它写在 .ply 文件上。但是当我按下它文件时 Meshlab 为我提供了一个 Error 。请找到以下内容,meshlab 可以允许打开该文件 Unespec
我正在使用一个简单的 .txt 文件测试层,其中包含:value = 0.4。解析器按预期工作,但是当我向该文件添加第二行时,出现错误: 错误:解析“LexToken(VALUE_KEY,'value
全部, 我正在用 python PLY 编写一个非常简单的解析器。它大部分完成了这项工作,但对于许多输入行,我从yacc收到语法错误。这是词法分析器和解析器代码,稍作修改以方便测试: tokens =
有没有办法对层词法分析器规则进行特殊处理? t_IDENT = r'[a-zA-Z_][0-9a-zA-Z_]*' t_OPERATOR = r'[<>=/*+-]+' t_DEFINE
我正在 python 中使用 PLY 构建解析器,当我运行解析器时,它会创建 3 个文件:parsetab.py、lextam.py 和 parse.out 如何才能不创建这些文件?有一个参数可以做到
我试图四处寻找这个问题的答案,但似乎找不到。我正在尝试使用 PLY 在 Python 中编写一个解析器作为一种编造的语言。我的 BNF 的简化版本如下所示: statement-list -> sta
我正在使用 Python 和 PLY 来解析类似 LISP 的 S 表达式,并且在解析函数调用时可以有零个或多个参数。我怎样才能将它放入 yacc 代码中。到目前为止,这是我的功能: def p_EX
所以我在 Ply 上编写了一个语法来识别基本的 C 语句,例如变量声明或 while 语句。现在,我想要做的是能够连接所有标记,然后打印它或让它在树上传播,如下所示: def p_whileStm
我正在尝试创建一个将我的脚本作为输入的解释器。我在编写正则表达式时遇到了一些问题。定义的标记之一是将所有字符串视为标记。 import ply.lex as lex import ply.yacc a
我想使用Python的PLY分析大量文本,其大小可能达到 1GB。 是否可以让 PLY 读取文本并将其解析为流,这样我就不必将整个内容加载到内存中?我想逐行检查文本,并让 PLY 对其进行分析。那可能
我正在尝试使用PLY lex / yacc解析PDF,而我却遇到了有关yacc解析规则的问题,该规则控制NUMBER标记,数组和indirect_references。 相关资料来源: def p_v
简而言之,我们如何区分使用了哪个规则 - 例子:- ''' p : a b | c | d '''所以假设我们需要为不同的规则编写不同的代码。那么有什么优雅的方法可以做到这一点。手册中给出的一种方法是
我在 PLY 中使用一个相当简单的解析器,我的规则之一采用以下形式: def p_things(p): ''' things : thing things things : t
我正在尝试构建一个 .PLY 解析器,以将存储为 .ply 文件的 3d 模型加载到半边数据结构网格中。 抱歉问了这么大的问题,我很冗长,我想确保我列出了所有的细节。因此,我将立即重申我的最终目标,以
我正在进入 .ply 文件的世界。我已经阅读了一些关于它们的内容,但是关于它们的格式的文档似乎与我的文件中的内容不太一致。我一直在尝试理解这篇文章 here,但我运气不佳。 这是我的 .ply 文件的
出于某种目的,我需要读取带有嵌入纹理的 PLY 文件(斯坦福三角格式)。我看到了 PLY 文件的几个规范,但找不到指定纹理映射语法的单个来源。似乎有很多库可以读取 PLY 文件,但大多数库似乎不支持纹
我使用 ply 作为我的 lex 解析器。我的规范如下: t_WHILE = r'while' t_THEN = r'then' t_ID = r'[a-zA-Z_][a-zA-Z0-9_]*'
我使用 ply 解析数据.我尝试使用空格作为词素的一部分。这里有一个简化的例子: from ply.lex import lex from ply.yacc import yacc tokens =
我是一名优秀的程序员,十分优秀!