- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
因此,在我不到 24 小时的 bison/flex 调查中,我看到很多文档表明左递归优于右递归。有些地方甚至提到,对于左递归,您需要 Bison 解析器堆栈上的常量空间,而右递归则需要 N 阶空间。但是,我找不到任何可以明确解释正在发生的事情的来源。
举个例子(只加减法的解析器):
扫描器:
%%
[0-9]+ {return NUMBER;}
%%
解析器:
%%
/* Left */
expression:
NUMBER
| expression '+' NUMBER { $$ = $1 + $3; }
| expression '-' NUMBER { $$ = $1 - $3; }
;
/* Right */
expression:
NUMBER
| NUMBER '+' expression { $$ = $1 + $3; }
| NUMBER '-' expression { $$ = $1 - $3; }
;
%%
对于 1+5-2 的例子,它似乎是左递归,解析器从词法分析器接收到 '1' 并看到 '1' 匹配 expression: NUMBER
并推送表达式值 1 到解析器堆栈。它看到 + 并插入。然后它看到 5 和表达式 (1),+ 和 5 匹配 expression: expression '+' NUMBER
所以它弹出两次,进行数学计算并将一个值为 6 的新表达式压入堆栈,然后重复减法。在任何一点,堆栈中最多有 3 个符号。所以它就像一个就地计算,从左到右运算。
对于右递归,我不确定为什么它必须将所有符号加载到堆栈上,但我将尝试描述为什么会出现这种情况。它看到 1 并与 expression: NUMBER
匹配,因此它将值为 1 的表达式压入堆栈。它将“+”压入堆栈。当它看到 5 时,我的第一个想法是 5 本身可以匹配 expression: NUMBER
,因此是一个值为 5 的表达式,然后它加上堆栈中的最后两个符号可以匹配 expression: NUMBER '+' expression
但我的假设是因为 expression
在规则的右边,所以它不能抢先将 5 作为表达式求值NUMBER 因为使用 LALR(1),它已经知道更多符号即将到来,所以它必须等到到达列表末尾?
长话短说;
有人可以详细解释一下 Bison 如何管理其解析堆栈,以及它如何使用解析器语法规则进行移位/归约?欢迎愚蠢/人为的例子!
最佳答案
使用 LR(自下而上)解析,每个非终结符在遇到其最后一个标记时被精确地减少。 (LALR 解析是一种简化的 LR 解析,它处理前瞻的精确度略低。)在减少非终端之前,它的所有组件都存在于堆栈中。所以如果你使用正确的递归并且你正在解析
NUMBER + NUMBER + NUMBER + NUMBER
在你到达结尾之前不会开始减少,因为每个 NUMBER
开始一个 expression
并且所有表达式都在最后一个 NUMBER
.
如果您使用左递归,每个 NUMBER
都会终止一个 expression
,因此每次遇到 NUMBER
时都会进行归约。
但这不是使用左递归的原因。您使用左递归是因为它准确地描述了语言。如果您有 7 - 2 - 1
,您希望结果为 4,因为这是代数规则所要求的:表达式被解析为 (7 - 2) - 1
,所以必须先减少 7 - 2
。使用右递归,您会错误地将其计算为 6,因为 2 - 1
会先减少。
大多数运算符关联到左侧,因此您使用左递归。对于偶尔向右关联的运算符,您需要正确的递归并且必须忍受堆栈的增长。没什么大不了的。您的机器有大量内存。
例如,考虑赋值。 a = b = 42
表示 a = (b = 42)
。如果你这样做是左关联的,你首先将 a
设置为 b
,然后尝试将某些东西设置为 42; (a = b) = 42
在大多数语言中都没有意义,这肯定不是预期的操作。
LL(自上而下)解析使用前瞻性来预测哪些生产将减少。它根本无法处理左递归,因为预测以递归循环结束:expression
以 expression
开头,而 expression
以 expression
... 并且解析器永远无法预测 NUMBER
。因此,对于 LL 解析器,您必须使用右递归,然后您的语法无法正确描述语言(假设该语言具有左关联运算符,通常是这种情况)。有些人不介意这一点,但我认为语法实际上应该指示正确的解析,而且我发现使语法可被自上而下的解析器解析所必需的修改是困惑且难以阅读的。您的里程可能会有所不同。
顺便说一下,“强制你的喉咙”是对试图给你好的建议的文档的一种非常吝啬的描述。持怀疑态度是件好事——如果你努力弄清楚事情为什么会这样运作,你就会更好地理解事情——但许多人只是想要好的建议。
关于recursion - 左/右递归和 Bison 解析堆栈行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48604590/
我一直在使用 AJAX 从我正在创建的网络服务中解析 JSON 数组时遇到问题。我的前端是一个简单的 ajax 和 jquery 组合,用于显示从我正在创建的网络服务返回的结果。 尽管知道我的数据库查
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
我在尝试运行 Android 应用程序时遇到问题并收到以下错误 java.lang.NoClassDefFoundError: com.parse.Parse 当我尝试运行该应用时。 最佳答案 在这
有什么办法可以防止etree在解析HTML内容时解析HTML实体吗? html = etree.HTML('&') html.find('.//body').text 这给了我 '&' 但我想
我有一个有点疯狂的例子,但对于那些 JavaScript 函数作用域专家来说,它看起来是一个很好的练习: (function (global) { // our module number one
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 8 年前。 Improve th
我需要编写一个脚本来获取链接并解析链接页面的 HTML 以提取标题和其他一些数据,例如可能是简短的描述,就像您链接到 Facebook 上的内容一样。 当用户向站点添加链接时将调用它,因此在客户端启动
在 VS Code 中本地开发时,包解析为 C:/Users//AppData/Local/Microsoft/TypeScript/3.5/node_modules/@types//index而不是
我在将 json 从 php 解析为 javascript 时遇到问题 这是我的示例代码: //function MethodAjax = function (wsFile, param) {
我在将 json 从 php 解析为 javascript 时遇到问题 这是我的示例代码: //function MethodAjax = function (wsFile, param) {
我被赋予了将一种语言“翻译”成另一种语言的工作。对于使用正则表达式的简单逐行方法来说,源代码过于灵活(复杂)。我在哪里可以了解更多关于词法分析和解析器的信息? 最佳答案 如果你想对这个主题产生“情绪化
您好,我在解析此文本时遇到问题 { { { {[system1];1;1;0.612509325}; {[system2];1;
我正在为 adobe after effects 在 extendscript 中编写一些代码,最终变成了 javascript。 我有一个数组,我想只搜索单词“assemble”并返回整个 jc3_
我有这段代码: $(document).ready(function() { // }); 问题:FB_RequireFeatures block 外部的代码先于其内部的代码执行。因此 who
背景: netcore项目中有些服务是在通过中间件来通信的,比如orleans组件。它里面服务和客户端会指定网关和端口,我们只需要开放客户端给外界,服务端关闭端口。相当于去掉host,这样省掉了些
1.首先贴上我试验成功的代码 复制代码 代码如下: protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
什么是 XML? XML 指可扩展标记语言(eXtensible Markup Language),标准通用标记语言的子集,是一种用于标记电子文件使其具有结构性的标记语言。 你可以通过本站学习 X
【PHP代码】 复制代码 代码如下: $stmt = mssql_init('P__Global_Test', $conn) or die("initialize sto
在SQL查询分析器执行以下代码就可以了。 复制代码代码如下: declare @t varchar(255),@c varchar(255) declare table_cursor curs
前言 最近练习了一些前端算法题,现在做个总结,以下题目都是个人写法,并不是标准答案,如有错误欢迎指出,有对某道题有新的想法的友友也可以在评论区发表想法,互相学习🤭 题目 题目一: 二维数组中的
我是一名优秀的程序员,十分优秀!