Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/magento/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bison 隐式优先_Bison_Parser Generator_Jison - Fatal编程技术网

Bison 隐式优先

Bison 隐式优先,bison,parser-generator,jison,Bison,Parser Generator,Jison,我正在阅读《Flex和Bison》一书,以了解解析器生成器的工作原理,其中有一个示例: calclist: /* nothing */ | calclist exp EOL { printf("= %d\n", $1); } ; exp: factor | exp ADD factor { $$ = $1 + $3; } | exp SUB factor { $$ = $1 - $3; } ; factor: term | fa

我正在阅读《Flex和Bison》一书,以了解解析器生成器的工作原理,其中有一个示例:

calclist: /* nothing */
        | calclist exp EOL { printf("= %d\n", $1); }
        ;

exp: factor
   | exp ADD factor { $$ = $1 + $3; } 
   | exp SUB factor { $$ = $1 - $3; }
   ;

factor: term
      | factor MUL term { $$ = $1 * $3; } 
      | factor DIV term { $$ = $1 / $3; }
      ;

term: NUMBER
    | ABS term { $$ = $2 >= 0? $2 : - $2; }
    ;

书中说,通过使用独立的非终结符号,上面的语法具有隐含的优先级。但是它是如何工作的呢?假设我们有下面的例子:1+3*2空格只是跳过我们读取的第一个标记1,它将被推到堆栈中作为数字或术语,或作为在语法中冒泡多长时间的因子?将从哪个语法规则检查下一个标记?为什么在这种语法中乘法的优先级高于加法?

这种语法的优先级是隐式的,而不是显式的,正如本文所说的,这是由于分解语法中的独立非终结符

通过你的1+3*2的例子,想象你自己是一台计算机在做语法分析,按照每一条指令去做。为了找到exp表达式,必须首先找到一个因子。您的其他选择是从查找exp开始,但必须找到一个因子。所以你必须找到一个因素。。。但要做到这一点,你必须找到一个术语,因为一个因子要么是一个术语,要么是一个以术语开头的因子。所以现在你必须找到一个术语,它要么是一个数字,要么是关键字ABS。因此,您可以接受语法术语中的1,它实际上是一个数字,并且您已经成功地在解析的第一部分找到了一个术语。现在从令牌流中删除1,留下+作为下一个令牌

现在你有了一个术语,你也定义了一个因子,但是为了完成一个因子的操作,你需要尝试更长的匹配:一个因子后面跟着MUL或DIV,后面跟着某物。您的下一个标记是+:它不是MUL,也不是DIV。因此,您必须停止解析factor并返回整个解析链,直到您的factor:1是factor,而下一个标记仍然是+

现在有了一个因子,定义上就有了一个exp,但是为了完成拥有exp的操作,再次需要尝试更长的匹配:exp后跟ADD或SUB,后跟某物。下一个标记仍然是+这实际上是一个ADD。。。因此,您必须继续执行exp ADD factor{$$=$1+$3};规则

此时,作为解析器,您将整个过程推到堆栈上,并再次开始寻找合适的非终结符——在本例中,是另一个因素。现在我们从一个因子的规则开始。您必须查找一个术语,如果您找到了一个术语,请尝试执行包含MUL或DIV的较长版本的规则。当您完成这部分工作时,您将看到*标记确实是MUL,您必须采用较长的规则,使因子结果使用规则中的因子MUL术语{$$=$1*$3;}部分。这将接受(也称为eat/use-up)3*2序列,并返回用于完成推送到解析堆栈上的规则的因子的值6


返回到push状态后,通过添加1并接受完整表达式来完成1+的解析。当然,1+6是7,因此语法返回正确的值。

这具有隐式优先权而不是显式优先权的原因确实正如文本所说的,这是由于经过分解的语法独立的非终结符

通过你的1+3*2的例子,想象你自己是一台计算机在做语法分析,按照每一条指令去做。为了找到exp表达式,必须首先找到一个因子。您的其他选择是从查找exp开始,但必须找到一个因子。所以你必须找到一个因素。。。但要做到这一点,你必须找到一个术语,因为一个因子要么是一个术语,要么是一个以术语开头的因子。所以现在你必须找到一个术语,它要么是一个数字,要么是关键字ABS。因此,您可以接受语法术语中的1,它实际上是一个数字,并且您已经成功地在解析的第一部分找到了一个术语。现在从令牌流中删除1,留下+作为下一个令牌

现在你有了一个术语,你也定义了一个因子,但是为了完成一个因子的操作,你需要尝试更长的匹配:一个因子后面跟着MUL或DIV,后面跟着某物。您的下一个标记是+:它不是MUL,也不是DIV。因此,您必须停止解析factor并返回整个解析链,直到您的factor:1是factor,而下一个标记仍然是+

现在有了一个因子,定义上就有了一个exp,但是为了完成拥有exp的操作,再次需要尝试更长的匹配:exp后跟ADD或SUB,后跟某物。下一个标记仍然是+这实际上是一个ADD。。。因此,您必须继续执行exp ADD factor{$$=$1+$3};规则

此时,作为解析器,您将整个过程推到堆栈上,然后再次开始工作 ng表示适当的非终结符-在本例中,是另一个因素。现在我们从一个因子的规则开始。您必须查找一个术语,如果您找到了一个术语,请尝试执行包含MUL或DIV的较长版本的规则。当您完成这部分工作时,您将看到*标记确实是MUL,您必须采用较长的规则,使因子结果使用规则中的因子MUL术语{$$=$1*$3;}部分。这将接受(也称为eat/use-up)3*2序列,并返回用于完成推送到解析堆栈上的规则的因子的值6


返回到push状态后,通过添加1并接受完整表达式来完成1+的解析。当然,1+6是7,因此语法返回正确的值。

优先级是加法和SUB操作数作为因子的结果,并且只有因子包含MUL和DIV运算符。ADD不与MUL竞争,因为MUL封装在一个术语中

从解析器的角度考虑这一点:在解析器考虑其与ADD操作符的关系之前,必须对术语表达式进行缩减,而这种缩减会删除MUL操作符

给定+X*Y,X*Y表达式被简化为术语,该术语是不再表示*运算符的单个语法符号,因此+运算符没有优先权问题;现在只是一个+术语

顺便说一下,语法使用了非传统的反向术语

这些是术语:A+B+C

这些是因素:A*B*C

项是级数的加法项,因子是整数或多项式的乘因子


这真的是这本教科书上的吗?在任何情况下,都可以试试Aho、Sethi、Ullman的《编译器:原理、技术和工具》。1988但经典。

优先级是加法和SUB操作数作为因子的结果,并且只有因子包含MUL和DIV运算符。ADD不与MUL竞争,因为MUL封装在一个术语中

从解析器的角度考虑这一点:在解析器考虑其与ADD操作符的关系之前,必须对术语表达式进行缩减,而这种缩减会删除MUL操作符

给定+X*Y,X*Y表达式被简化为术语,该术语是不再表示*运算符的单个语法符号,因此+运算符没有优先权问题;现在只是一个+术语

顺便说一下,语法使用了非传统的反向术语

这些是术语:A+B+C

这些是因素:A*B*C

项是级数的加法项,因子是整数或多项式的乘因子


这真的是这本教科书上的吗?在任何情况下,都可以试试Aho、Sethi、Ullman的《编译器:原理、技术和工具》。谢谢你的回答帮助了我。谢谢你的回答帮助了我。