- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我试图在 LL 解析算法的上下文中理解最左边的推导。这link从生成的角度解释它。即它展示了如何遵循最左推导从一组规则中生成特定的标记序列。
但是我在想相反的方向。给定一个标记流和一组语法规则,如何通过最左推导找到应用一组规则的正确步骤?
让我们继续使用上述链接中的以下语法:
并且给定的标记序列是:1 2 3
一种方法是这样的:
1 2 3
-> D D D
-> N D D (rewrite the *left-most* D to N according to the rule N->D.)
-> N D (rewrite the *left-most* N D to N according to the rule N->N D.)
-> N (same as above.)
但是还有其他方法可以应用语法规则:
1 2 3 -> D D D -> N D D -> N N D -> N N N
或
1 2 3 -> D D D -> N D D -> N N D -> N N
但只有第一个推导以单个非终结符结束。
随着 token 序列长度的增加,可以有更多的方式。我认为要推断出正确的推导步骤,需要两个先决条件:
给出这 2 个后,找到推导步骤的算法是什么?我们是否必须使最终结果成为单个非终结符?
最佳答案
LL解析的一般过程包括重复:
预测堆栈顶部语法符号的产生式(如果该符号是非终结符号),并用产生式的右侧替换该符号。 p>
将堆栈中的顶部语法符号与下一个输入符号匹配,同时丢弃它们。
匹配操作没有问题,但预测可能需要 oracle。但是,出于此解释的目的,只要预测有效,预测的机制就无关紧要了。例如,可能是对于一些小整数 k
,k
输入符号的每个可能序列最多只与一个可能的产生式一致,在这种情况下,您可以使用查找表。在那种情况下,我们说文法是LL(k)
。但是你可以使用任何机制,包括魔法。只需要预测总是准确的。
在此算法的任何步骤中,部分派(dispatch)生的字符串是附加在堆栈上的消耗输入。最初没有消耗的输入,堆栈仅由开始符号组成,因此部分派(dispatch)生的字符串(应用了 0 次派生)。由于消耗的输入仅由终端组成,并且算法只会修改堆栈的顶部(第一个)元素,因此很明显,部分派(dispatch)生的字符串系列构成了最左边的派生。
如果解析成功,整个输入将被消耗并且堆栈将为空,因此解析结果是从起始符号开始的输入的最左边推导。
这是您示例的完整解析:
Consumed Unconsumed Partial Production
Input Stack input derivation or other action
-------- ----- ---------- ---------- ---------------
N 1 2 3 N N → N D
N D 1 2 3 N D N → N D
N D D 1 2 3 N D D N → D
D D D 1 2 3 D D D D → 1
1 D D 1 2 3 1 D D -- match --
1 D D 2 3 1 D D D → 2
1 2 D 2 3 1 2 D -- match --
1 2 D 3 1 2 D D → 3
1 2 3 3 1 2 3 -- match --
1 2 3 -- -- 1 2 3 -- success --
如果您阅读最后两列,您可以看到从 N
开始到 1 2 3
结束的推导过程。在此示例中,只能使用魔法进行预测,因为规则 N → N D
对于任何 k 都不是 LL(k);使用右递归规则 N → D N
将允许 LL(2) 决策过程(例如,“如果至少有两个未使用的输入,则使用 N → D N
token ;否则 N → D
".)
您尝试生成的以 1 2 3
开头并以 N
结尾的图表是一个自下而上 解析。使用 LR 算法的自底向上解析对应于最右推导,但推导需要向后读取,因为它以开始符号结束。
关于algorithm - 说明 token 流上的最左边的推导,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41531642/
运行以下代码片段,我没有收到任何错误,并且得到了预期的结果。但是,由于第二个模板实例化是不明确的 ( both type specifiers are references ),我担心这可能不是定义的
考虑以下示例: #include struct A {}; template void f() { static_assert(std::is_same_v); // #1 A&
从 DH 协商中派生的 secret 派生出一个比方说 128 位 AES key 的正确(可接受的)方法是什么? 使用前 128 位 对 secret 进行哈希处理并使用前 128 位 使用一些更复
从 DH 协商中派生的 secret 派生出一个比方说 128 位 AES key 的正确(可接受的)方法是什么? 使用前 128 位 对 secret 进行哈希处理并使用前 128 位 使用一些更复
我对编写模板元编程比较陌生,这可能是我找不到解决这个问题的原因。问题是这样的:我正在开发一个数学库,它有很多函数,比如确定整数或 std::initializer_list 的质数,将整数更改为罗马数
我在 Android Oreo 源代码中阅读了一些我不太理解的代码。 首先,类IOMXNode有一个函数: class IOMXNode : public IInterface { public: +
有很多关于模板参数推导的讨论和澄清,特别是引用折叠和“通用引用”。本题通过相关细节:How does auto deduce type? ,而 Scott Meyers 的这篇论文更详细,可能会提供更
我将 Java 中的许多假设带到了我对 C++ 的学习中,这似乎再次难倒了我。我没有足够的词汇量来 Eloquent 地说出我希望从以下程序中看到什么,所以我只展示它并说出我希望看到的内容: #inc
对于下面的程序,Clang 5 (trunk) 报告 IsNoexcept 不可推导,而 GCC 7.1 会出现段错误。 标准(草案)对此有何评论?这是编译器 QOI 问题吗? static_asse
我最近发现,在 lambda 中按值捕获 const 对象意味着 labmda 主体(即 lambda 的数据成员)内的变量也是 const. 例如: const int x = 0; auto fo
我是否有机会推断出 PHP Closure 参数类型信息?考虑这个例子: 5, 'b' => 10]); } else { call_user_func($closure, 5, 10);
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,
对于上述 svm 的拉格朗日函数,我可以得到如下的偏导数: 但是,我不明白如何将它们插入拉格朗日以导出对偶形式? W可以被替换,但是b去哪里了? 有人可以解释一下并给出详细步骤吗? 最佳答案 你的拉格
我正在寻找一些算法、程序或函数来推断变量的创建方式,只要我提供其他变量即可。我认为计算机程序员会称之为“反编译”,而架构师会称之为“逆向工程”,但我想我不知道统计学家会怎么调用它......或者是否有
这就是我的简单类的样子。 template class A { T first; T second; public: A(T f, T s) : first(f), second(s) {}; te
这个问题在这里已经有了答案: Is it possible to figure out the parameter type and return type of a lambda? (5 个答案)
我有一个函数需要两个 std::function s 作为参数。第二个函数的参数与第一个函数的结果类型相同。 我写了一个这样的函数模板: template void examplFunction(st
O'reilly Optimizing SQL Statments Book的Explaining MySQL Explain章节,最后有这个问题。 The following is an examp
举例 template void function(T&& arg) 有人可以详细解释它是如何结束函数签名变成左值的 T& 和传入的右值的 T&& 吗?我知道不知何故(需要标准行)T -> T& 在
我正在开发用于 EMV 交易的软件,但我面临着雇佣我的公司的文档严重缺乏的问题。 其中之一是关于用于生成 ARQC 的 MKD(在第一个 GENERATE AC 期间)。我从消息请求中知道IAD如下:
我是一名优秀的程序员,十分优秀!