- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我有以下 Bison 语法:
%error-verbose
%{
#include "node.h"
NBlock *programBlock;
#define YYDEBUG 1
extern int yylex();
void yyerror(const char *s) { printf("Error: %s\n", s); }
%}
%union {
Node *node;
NBlock *block;
NBody *body;
NHeader *header;
NExpression *expression;
NStatement *statement;
NIdentifier *identifier;
NVariableDeclaration *variableDeclaration;
NDoWhileStatement *doWhileStatement;
NWhileStatement *whileStatement;
NIfStatement *ifStatement;
NForStatement *forStatement;
std::vector<NVariableDeclaration*> *variableDeclarations;
std::vector<NExpression*> *expressions;
std::vector<NStatement*> *statements;
std:string *string;
int token;
}
/*
The %token directive is used to associate a type to a terminal symbol.
%token <type> 'terminal_list'
associates the specific type <type> to each terminal in 'terminal_list'.
The type <type> is the same used in the %union declaration
*/
%token <string> TIDENTIFIER TINTEGER TDOUBLE
%token <token> TCEQ TCNE TCLT TCLE TCGT TCGE TEQUAL
%token <token> TLPAREN TRPAREN TLBRACE TRBRACE TCOMMA TDOT
%token <token> TPLUS TMINUS TMUL TDIV TDO TDOUBLE_TYPE TINT_TYPE
%token <token> TELSE TFOR TIF TSEMICOLON TTHEN TWHILE
/*
The %type directive is used to associate a type to a nonterminal symbol.
%type <type> nonterminal_list
associates the specific type <type> to each nonterminal in 'nonterminal_list'.
The type <type> is the same used in the %union declaration
*/
%type <expression> expression term factor
%type <block> program body header tail statements
%type <statement> statement forStatement ifStatement doWhileStatement whileStatement variableDeclaration
%type <token> comparison
%type <string> identifier_type
/*
Operator precedence for mathematical operators
*/
%left TPLUS TMINUS
%left TMUL TDIV
%left TCEQ TCNE TCLT TCLE TCGT TCGE
/*
Start grammar symbol
*/
%start program
%%
program: TLBRACE body TRBRACE { printf("Reduce body to program\n"); }
;
body: header TLBRACE block TRBRACE tail { printf("Reduce header block tail to body\n"); }
;
header: TLBRACE variableDeclarations TRBRACE { printf("Reduce variableDeclarations to header\n"); }
| TLBRACE TRBRACE { printf("Reduce empty to header\n"); }
;
variableDeclarations: variableDeclaration TSEMICOLON { printf("Reduce variable declaration to header\n"); }
| variableDeclarations variableDeclaration TSEMICOLON { printf("Reduce variable declaration list to header\n"); }
;
tail: TLBRACE statements TRBRACE { printf("reduce statement list to tail\n"); }
| TLBRACE TRBRACE { printf("Reduce empty to tal\n"); }
;
statements: statement TSEMICOLON { printf("Reduce statement to statement list\n"); }
| statements statement TSEMICOLON { printf("Reduce statement list to statement list\n"); }
;
statement: ifStatement { printf("Reduce if to statement\n"); };
| forStatement { printf("Reduce for to statement\n"); };
| doWhileStatement { printf("Reduce doWhile to statement\n"); };
| whileStatement { printf("reduce while to statement\n"); }
| TIDENTIFIER TEQUAL expression { printf("Reduce assignment to expression\n"); }
;
forStatement: TFOR TLPAREN expression TSEMICOLON expression TSEMICOLON expression TRPAREN block { printf("Reduce for to for statement\n"); }
;
ifStatement: TIF expression TTHEN block { printf("Reduce if to if statement\n"); }
| TIF expression block TELSE block { printf("Reduce ifelse to if statement\n"); }
;
doWhileStatement: TDO block TWHILE expression { printf("reduce dowhile to while statement\n"); }
;
whileStatement: TWHILE block expression { printf("Reduce while to while statement\n"); }
;
block: TLBRACE statements TRBRACE { printf("Reduce statement list to block\n"); }
| TLBRACE TRBRACE { printf("Reduce empty to block\n"); }
;
variableDeclaration: identifier_type TIDENTIFIER { printf("reduce uninitialized identifier to variable declaration\n"); }
| identifier_type TIDENTIFIER TEQUAL expression { printf("Reduce initialized identifier to variable declaration\n"); }
;
identifier_type: TINT_TYPE { printf("Reduce int to identifier type\n"); }
| TDOUBLE_TYPE { printf("Reduce double to identifier type\n"); }
| { printf("Reduce empty to identifier type\n"); }
;
expression: term { printf("Reduce term to expresson\n"); }
| expression comparison expression { printf("Reduce comparison to expression\n"); }
| expression TPLUS term { printf("Reduce addition to expression\n"); }
| expression TMINUS term { printf("Reduce subtraction to expression\n"); }
;
term: factor { printf("Reduce factor to term\n"); }
| term TMUL factor { printf("Reduce multiplication to term\n"); }
| term TDIV factor { printf("Reduce division to term\n"); }
;
factor: TLPAREN expression TRPAREN { printf("Reduce nested expression to expression\n"); }
| TMINUS factor { printf("Reduce -factor to factor\n"); }
| TIDENTIFIER { printf("Reduce identifier to factor\n"); }
| TINTEGER { printf("Reduce integer to numeric\n"); }
| TDOUBLE { printf("Reduce double to numeric\n"); }
;
comparison: TCEQ { printf("Reduce eq to comparison\n"); }
| TCNE { printf("Reduce ne to comparison\n"); }
| TCLT { printf("Reduce lt to comparison\n"); }
| TCLE { printf("Reduce le to comparison\n"); }
| TCGT { printf("reduce gt to comparison\n"); }
| TCGE { printf("Reduce ge to comparison\n"); }
;
我遇到了 8 个我不知道如何解决的 shift/reduce 冲突。
以下是我使用 --report=all 参数生成的 parser.output 文件的一部分。这是受 8 个 shift/reduce 冲突影响的状态:
State 79
29 expression: expression . comparison expression
29 | expression comparison expression . [TCEQ, TCNE, TCLT, TCLE, TCGT, TCGE, TRPAREN, TLBRACE, TPLUS, TMINUS, TSEMICOLON, TTHEN]
30 | expression . TPLUS term
31 | expression . TMINUS term
40 comparison: . TCEQ
41 | . TCNE
42 | . TCLT
43 | . TCLE
44 | . TCGT
45 | . TCGE
TCEQ shift and go to state 56
TCNE shift and go to state 57
TCLT shift and go to state 58
TCLE shift and go to state 59
TCGT shift and go to state 60
TCGE shift and go to state 61
TPLUS shift and go to state 62
TMINUS shift and go to state 63
TCEQ [reduction with rule 29 (expression)]
TCNE [reduction with rule 29 (expression)]
TCLT [reduction with rule 29 (expression)]
TCLE [reduction with rule 29 (expression)]
TCGT [reduction with rule 29 (expression)]
TCGE [reduction with rule 29 (expression)]
TPLUS [reduction with rule 29 (expression)]
TMINUS [reduction with rule 29 (expression)]
$default reduction with rule 29 (expression)
comparison go to state 64
如果我理解得很好,问题是解析器不知道是继续读取另一段文本还是立即减少规则表达式:表达式比较表达式。
我会说立即减少是正确的。但如果我这是正确的,那么我该如何强制立即减少而不是转移?
最佳答案
您的语法有歧义——像 1 < 2 < 3
这样的输入可以解析为 (1 < 2) < 3
或 1 < (2 < 3)
.
有两种方法可以解决这个问题——要么添加 %left
/%right
/%nonassoc
指令使用 bison 的内部优先级处理,或引入额外级别的规则来处理它。
现在,对于您的其他运算符 ( *
/
+
-
),您正在同时执行这两项操作——这通常是一个错误,您只想执行其中一项。但是,如果您同时执行这两项操作,附加规则将优先,优先指令将被忽略,有时会导致令人惊讶的问题。
像这样的关系的“正常”处理是说你不能有多个关系(1 < 2 < 3
是一个语法错误,不应该被左递归或右递归解析。)要用额外的规则来做到这一点,您会将表达式规则更改为:
expression: add_expression
| add_expression comparison add_expression
;
add_expression: term
| add_expression TPLUS term
| add_expression TMINUS term
;
要使用优先指令,去掉 term
, factor
, 和 comparison
(将它们全部移动到 expression
并添加:
%nonassoc TCEQ TCNE TCLT TCLE TCGT TCGE
%left TPLUS TMINUS
%left TMUL TDIV
关于c - 无法修复 Bison 语法中的移位/减少冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15662911/
我想将这个无符号数:1479636484000 向右移动 7 位。这在 JavaScript 中可能吗? 两者 1479636484000 >> 7 和 1479636484000 >>> 7 返回错
鉴于以下代码: import matplotlib.pyplot as plt import numpy as np x = [1.0, 1.1, 2.0, 5.7] y = np.arange(le
我有一个低级键盘钩子(Hook),目前允许我从任何应用程序(包括游戏)中控制媒体播放器。 它通过查看捕获的特定击键来工作。 我想扩展它以查找键的组合。我可以对一些逻辑进行硬编码,但我觉得必须有一种更合
我需要一些帮助来理解这段C代码。我不知道这里的“L”和“\”是什么?请也说明一点:) #define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>2
我正在查看一段代码: int result = 0 ; char byte = foo[j] for (i = 7 ; i>0 ; i--) { byte = (byte & ~0x1)>>1
我们有一个项目要求我们编写一个程序,允许用户输入一系列数字“将数字读入数组以进行进一步处理,用户通过输入负数表示他们已完成(负数不用于计算),在读取所有数字后执行以下操作,总结输入的#,计算输入的#,
锁定。有disputes about this question’s content正在解决中。它目前不接受新的答案或互动。 def menu(): choice = input("Pres
为什么如果 int x = -1 // binary: 11111111111111111111111111111111 x = x >>> 31; 我们有 000000000000000000000
我的问题其实应该很简单:我有一个玩家对象数组。(玩家[])我想要一个函数来旋转这个数组直到一个索引: public void rotateArray(Object[] array, int index
我有一个编码为 boost 动态位集的数字列表。我根据此列表中的任何数字可以采用的最大值动态选择此位集的大小。所以假设我有从 0 到 7 的数字,我只需要三位,我的字符串 0,2,7 将被编码为000
我能想到一些令人讨厌的低效方法来完成这项任务,但我想知道最好的方法是什么。 例如,我想复制一个字节中从第 3 位开始的 10 个字节,并像往常一样复制到一个指针。 有没有比一次复制一个移位字节更好的方
我正在尝试为该问题添加更多规则,并且该规则一直给我带来这种转变/减少冲突的能力,我不知道为什么会这样做,并且在过去的24小时内我一直在尝试解决问题 FuncDecl : RetTyp
This question already has answers here: Why does it make a difference if left and right shift are us
我在 Perl 中遇到这个问题已经有几天了,在搜索了无数的手册页、perldocs 和谷歌搜索了太多的搜索词之后,希望这里有人能帮助我。 我得到两个表示十六进制值的字符串,即“FFFF”,而不是 Pe
我有一个主 div,两个 div 水平并排放置在这个父 div 中。 .parent{ height: 360px; margin-top: 0px; bo
我想 float 我的元素列表并从第二个元素创建一个移动效果。 如何避免第二个 .item 之后的“清除”行为? .shift { float: right; width: 50%;
我正在使用 SSE3 优化我的代码。代码中有一点迫使我将 vector 中的所有元素移动一个元素 v[0] = 0 //v is some char* and N = v.size() for(i
.file "calcnew.c" .text .globl calcnew .type calcnew, @function calcnew:
我有一个点对象: class Point { final int x,y; ... } 因为这些点将在我的代码中到处使用/创建,所以我想开始使用 guavas 缓存。不幸的是
x = "Foo 890 bar *()" 如何将包括 "*()" 在内的小写字母“未移位”返回到 890?期望的结果: foo 890 bar 890 不需要的: x.lower() => "foo
我是一名优秀的程序员,十分优秀!