- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
最近我发现了 python 模块 pyparsing
,这是一个通过编写语法而不是解析器来解析数据的好工具。我对上下文无关语法的概念还很陌生,所以请纠正这个问题中的任何错误假设。
Pyparsing 可以实现 BNF ( Backus–Naur Form ) 上下文无关语法。这个文法可以递归,但是能不能有前瞻性呢?自从我偶然发现 this question 以来,我一直在想这个问题的答案。 .让我给你一个具体的例子。考虑字符串:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
让语法看起来像这样:
<number> :: __<digit>__
<block> :: <number>(x) (<number> <number> <number> .... x times)
即读取第一个数字标记,将其保存为 x
,然后使用下一个 x
数字并将它们组合在一起。解析后的行应如下所示:
[[1, 2], [3, 4, 5, 6], [7, 8, 9, 10, 11, 12, 13, 14], [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]]
我已经使用 pyparsing 编写了一个简单的 python MWE 不,所以很清楚我想做什么:
A = range(1,31)
B, sub_b = [], []
consume = 0
for a in A:
if consume:
sub_b.append(a)
consume -= 1
else:
if sub_b: B.append(sub_b)
sub_b = [a,]
consume = a
B.append(sub_b)
print B
两个(相关)问题:这可以用 BNF 上下文无关文法来完成吗?如果是/否,我该如何使用 pyparsing
来实现?
最佳答案
在上下文无关语法或常规语法中没有参数化大小这样的东西。像您的consume
这样的数值参数不是CFG 模型的一部分,可以证明以不同的方式获得效果是不可能的。不过,您可以为任何固定 长度编写产生式,因此您可以为长度为 1、长度为 2、长度为 3 等的 block 编写产生式:
<block3> :: <number> <number> <number>
或者,类似地,匹配长度作为前缀甚至作为后缀:
<block3a> :: 3 <number> <number> <number>
<block3b> :: <number> <number> <number> 3
等因此,要执行您想要的操作,您只需要一个包含此类规则的语法,对于您可能需要的所有 N
。
给定的 CFG 将仅包含有限数量的此类作品。在数学上不可能编写可以处理无限参数化大小的 CFG(以 BNF 或任何其他形式),无论是作为前缀还是作为后缀。实际上,您可以根据需要使用新作品即时更新您的 CFG。例如,读取一个数字 N
并为您的语法创建一个规则 blockN
(如果它不存在)。但是没有单个 CFG 可以捕获无限制的参数化大小。
编辑,因为您还询问了上下文相关语法:这仍然不行。问题是整数运算的使用,而不是语法的类。 任何乔姆斯基层次结构上的形式语言都是根据有限数量的符号(标记)定义的,并且由于是无限多的整数,因此不能为它们分配不同的含义(请注意,您的解析过程依赖于整数算术)。
如果您要将长度预处理为包含尽可能多的星星的序列 (* * * 4 7 10
),则 CFG 解析器很简单:
<group> :: * <group> <number>
<group> :: * <number>
这就是所谓的a^n b^n
语言。您也可以使用表示“十”等的符号。但是如果没有预处理,唯一的解决方案(以及您的过程或图灵机在实践中所做的)是解释语法中的数字符号。例如,将“21”解析为十十一。我怀疑这可以在 CFG 中完成(问题是处理任意长的数字,而没有针对数百万、数十亿等的单独规则),但我不太确定。无论哪种方式,它都只是作为一个学术练习才有趣,因为使用实整数要容易得多。我敢肯定,人们已经用整数研究了形式语言的属性,但我对此无话可说。
关于python - BNF 可以处理远期消费吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10030526/
我正在写一个小语法作为类练习,我的教授并没有真正具体说明什么是合法的 BNF 表达式。 BNF 语法应该识别这种形式的字符串:AB、AABB、AAABBB、A...B...(一般形式:AnBn) 所以
如何将此 BNF 转换为 EBNF? ::= var ; ::= {;} ::= {,} : ::= {} ::= | | _ 最佳答案 EBNF 或 Extended Back
我正在开展一个学校项目,需要我解析 BNF 语法。我有点困惑管道符 (|)(我认为它的意思是“或”)在规则中扮演什么角色。 例如,如果我有以下内容: ::= b c d | e f g 哪个终端是
我需要将以下语法转换为 EBNF: -> = -> A|B|C -> + | * | * |( ) | 我目前取得的进展如下: -> = =
我正在尝试学习 BNF 并尝试组装一些 Z80 ASM 代码。由于我对这两个领域都是新手,我的问题是,我是否走在正确的轨道上?我正在尝试将 Z80 ASM 的格式编写为 EBNF,以便我可以找出从哪里
有谁知道我在哪里可以获得 LOGO 的 BNF 或 EBNF编程语言? 最佳答案 BNF 语法在某些情况下可能不太有用...... 编写一个与现有/历史实现准确兼容的 LOGO 并不是一件容易的事(我
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 1 年前。
最近在想下面的BNF A -> x | yA | yAzA where x,y,z are terminals. 我很确定这个语法是模棱两可的,但是如何使它不含糊呢? 最佳答案 如果一个特定的字符串可
是否有正则表达式的 BNF 语法? 最佳答案 你可以看到一个 Perl regexp (显示 a little more in detail here ,由 edg 发布) 关于正则表达式 BNF 语
我使用这个 BNF 来解析我的脚本: {identset} = {ASCII} - {"\{\}}; //<--all ascii charset except '\"' '{' and '}
无法为字符序列(可能为空)提出 BNF 语法,以逗号分隔,但不以逗号开头或结尾, 所以这没问题: ::= | , | 但这会产生类似 A, :-( 最佳答案 空字符序列给你带来了麻烦。您
我有一项作业要纠正一个不明确的 BNF,但我完全迷失了。我知道这不是一个真正的编程问题,如果这不是这些板的合适问题,我会很乐意删除它。有没有什么好的网站可以让我了解更多有关 BNF 的信息?我正在处理
我该如何描述语言 A → AA | ( A ) | ε 使用正则表达式生成? 最佳答案 正则表达式接受来自正则语言的字符串。 FSM 也可以接受常规语言。 在您的语言中,您必须匹配的括号数量可能是无限
在使用 Prolog DCG 解析输入时,最好有一个语法的 BNF 伴随。 例如: BNF ::= ::= ::= ::= a ::= the ::= cat ::= mou
我需要迭代形式的产生规则的符号: 例如:输入 ::= = | <> | = | > | in ::= | ; 所以我需要派生一个正则表达式来分割文本。这是我到目前为止所拥有的 (?:\s|^
我继承了一个 ANTLR 语法,现在我需要编写一个很好的、古老的、类似 YACC/BISON 的解析器(具体来说,我使用 PLY for python)。有许多奇怪的规则,我现在正在努力解决以下问题:
我需要解析一个不是我设计的简单专有语言,所以我不能改变语言。我需要 C# 中的结果,所以我一直在使用 TinyPG,因为它非常易于使用,并且不需要外部库来运行解析器。 TinyPG 生成一个简单的 L
最近我发现了 python 模块 pyparsing,这是一个通过编写语法而不是解析器来解析数据的好工具。我对上下文无关语法的概念还很陌生,所以请纠正这个问题中的任何错误假设。 Pyparsing 可
好吧,我不确定我应该如何使用递归下降解析来编写一个函数来解析如下语法。事实上,我不确定我是否做对了...... BNF: A : B | A '!' B : '[' ']' 伪代码: f() {
有一个我可以找到流行语言的Backus -Naur形式或BNF语法吗?每当我进行搜索时,我都不会出现太多,但是我认为它们必须在某个地方出版。我最有兴趣看到一个用于Objective-C和MySQL的一
我是一名优秀的程序员,十分优秀!