Parsing 野牛简易计算器
我不熟悉语法分析。以下是Bison中解析器的代码片段: 解析器.y:Parsing 野牛简易计算器,parsing,bison,flex-lexer,Parsing,Bison,Flex Lexer,我不熟悉语法分析。以下是Bison中解析器的代码片段: 解析器.y: %{ #include <stdio.h> %} /* declare tokens */ %token NUMBER %token ADD SUB MUL DIV ABS %token EOL %% calclist: /* nothing */ | calclist exp EOL { printf("= %d\n", $1); } ; exp: factor | exp AD
%{
#include <stdio.h>
%}
/* declare tokens */
%token NUMBER
%token ADD SUB MUL DIV ABS
%token EOL
%%
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; }
;
%%
main(int argc, char **argv)
{ yyparse();
}
yyerror(char *s)
{ fprintf(stderr, "error: %s\n", s);
}
感谢您的帮助
谢谢。如果你要求,野牛解析器会很高兴地告诉你他们在做什么,使用野牛的 为了获得以下跟踪,我使用了您的输入文件,只做了最小的更改:
- 我修复了没有返回值的原型(
和main
),并添加了yyerror
和yylex
的前向声明yyerror
- 我修复了
中的calclist
,以打印表达式(printf
)的值,而不是没有值的calclist本身$2
- 我将单字符标记(
,ADD
等)更改为实际的单字符(SUB
,'+'
等),以简化扫描仪-
- 我添加了一个简单的lexer
- 最后,我通过添加
到yydebug=1启用了跟踪
函数,并使用main
标志调用bison-t
-v
选项选择野牛
$ ./trace <<< '10 - 3 * 2 + 6'
Starting parse
Entering state 0
Reducing stack by rule 1 (line 13):
-> $$ = nterm calclist ()
Stack now 0
Entering state 1
Reading a token: Next token is token NUMBER ()
Shifting token NUMBER ()
Entering state 3
Reducing stack by rule 10 (line 22):
$1 = token NUMBER ()
-> $$ = nterm term ()
Stack now 0 1
Entering state 9
Reducing stack by rule 7 (line 19):
$1 = nterm term ()
-> $$ = nterm factor ()
Stack now 0 1
Entering state 8
Reading a token: Next token is token '-' ()
Reducing stack by rule 4 (line 16):
$1 = nterm factor ()
-> $$ = nterm exp ()
Stack now 0 1
Entering state 7
Next token is token '-' ()
Shifting token '-' ()
Entering state 14
Reading a token: Next token is token NUMBER ()
Shifting token NUMBER ()
Entering state 3
Reducing stack by rule 10 (line 22):
$1 = token NUMBER ()
-> $$ = nterm term ()
Stack now 0 1 7 14
Entering state 9
Reducing stack by rule 7 (line 19):
$1 = nterm term ()
-> $$ = nterm factor ()
Stack now 0 1 7 14
Entering state 18
Reading a token: Next token is token '*' ()
Shifting token '*' ()
Entering state 15
Reading a token: Next token is token NUMBER ()
Shifting token NUMBER ()
Entering state 3
Reducing stack by rule 10 (line 22):
$1 = token NUMBER ()
-> $$ = nterm term ()
Stack now 0 1 7 14 18 15
Entering state 19
Reducing stack by rule 8 (line 20):
$1 = nterm factor ()
$2 = token '*' ()
$3 = nterm term ()
-> $$ = nterm factor ()
Stack now 0 1 7 14
Entering state 18
Reading a token: Next token is token '+' ()
Reducing stack by rule 6 (line 18):
$1 = nterm exp ()
$2 = token '-' ()
$3 = nterm factor ()
-> $$ = nterm exp ()
Stack now 0 1
Entering state 7
Next token is token '+' ()
Shifting token '+' ()
Entering state 13
Reading a token: Next token is token NUMBER ()
Shifting token NUMBER ()
Entering state 3
Reducing stack by rule 10 (line 22):
$1 = token NUMBER ()
-> $$ = nterm term ()
Stack now 0 1 7 13
Entering state 9
Reducing stack by rule 7 (line 19):
$1 = nterm term ()
-> $$ = nterm factor ()
Stack now 0 1 7 13
Entering state 17
Reading a token: Next token is token '\n' ()
Reducing stack by rule 5 (line 17):
$1 = nterm exp ()
$2 = token '+' ()
$3 = nterm factor ()
-> $$ = nterm exp ()
Stack now 0 1
Entering state 7
Next token is token '\n' ()
Shifting token '\n' ()
Entering state 12
Reducing stack by rule 3 (line 15):
$1 = nterm calclist ()
$2 = nterm exp ()
$3 = token '\n' ()
= 10
-> $$ = nterm calclist ()
Stack now 0
Entering state 1
Reading a token: Now at end of input.
Shifting token $end ()
Entering state 2
Stack now 0 1 2
Cleanup: popping token $end ()
Cleanup: popping nterm calclist ()
$。/trace$$=nterm术语()
现在堆叠0 1
进入第9国
按规则7减少堆栈(第19行):
$1=NTRM术语()
->$$=NTRM系数()
现在堆叠0 1
进入第8国
正在读取令牌:下一个令牌是令牌“-”()
按规则4(第16行)减少堆栈:
$1=NTRM系数()
->$$=NTRM exp()
现在堆叠0 1
进入第7国
下一个标记是标记“-”()
移位标记'-'()
进入第14国
读取令牌:下一个令牌是令牌号()
移动令牌号()
进入第3国
按照规则10(第22行)减少堆栈:
$1=令牌编号()
->$$=内部术语()
现在堆叠0 1 7 14
进入第9国
按规则7减少堆栈(第19行):
$1=NTRM术语()
->$$=NTRM系数()
现在堆叠0 1 7 14
进入第18国
正在读取令牌:下一个令牌是令牌“*”()
移位标记“*”()
进入第15国
读取令牌:下一个令牌是令牌号()
移动令牌号()
进入第3国
按照规则10(第22行)减少堆栈:
$1=令牌编号()
->$$=内部术语()
现在堆叠017141815
进入第19国
按规则8(第20行)减少堆栈:
$1=NTRM系数()
$2=令牌“*”()
$3=国际术语()
->$$=NTRM系数()
现在堆叠0 1 7 14
进入第18国
正在读取令牌:下一个令牌是令牌“+”()
按规则6(第18行)减少堆栈:
$1=NTRM exp()
$2=标记'-'()
$3=NTRM系数()
->$$=NTRM exp()
现在堆叠0 1
进入第7国
下一个标记是标记“+”()
移位标记“+”()
进入第13国
读取令牌:下一个令牌是令牌号()
移动令牌号()
进入第3国
按照规则10(第22行)减少堆栈:
$1=令牌编号()
->$$=内部术语()
现在堆叠0 1 7 13
进入第9国
按规则7减少堆栈(第19行):
$1=NTRM术语()
->$$=NTRM系数()
现在堆叠0 1 7 13
进入第17国
正在读取令牌:下一个令牌是令牌“\n”()
按规则5(第17行)减少堆栈:
$1=NTRM exp()
$2=标记“+”()
$3=NTRM系数()
->$$=NTRM exp()
现在堆叠0 1
进入第7国
下一个令牌是令牌“\n”()
正在转移标记“\n”()
进入第12国
按规则3减少堆栈(第15行):
$1=nterm calclist()
$2=NTRM exp()
$3=令牌“\n”()
= 10
->$$=nterm calclist()
现在堆叠0
进入状态1
正在读取令牌:现在位于输入的末尾。
移动令牌$end()
进入状态2
现在堆栈0 1 2
清理:弹出标记$end()
清理:弹出nterm calclist()
一个问题-从输入读取标记10并将其减少到数字-->术语-->因子
后,为什么不按照规则exp:factor
(规则7)将其进一步减少到exp
。相反,它继续读取下一个标记(即“-”号?@Raj:它使用规则7进行缩减。这在痕迹中很清楚。
$ ./trace <<< '10 - 3 * 2 + 6'
Starting parse
Entering state 0
Reducing stack by rule 1 (line 13):
-> $$ = nterm calclist ()
Stack now 0
Entering state 1
Reading a token: Next token is token NUMBER ()
Shifting token NUMBER ()
Entering state 3
Reducing stack by rule 10 (line 22):
$1 = token NUMBER ()
-> $$ = nterm term ()
Stack now 0 1
Entering state 9
Reducing stack by rule 7 (line 19):
$1 = nterm term ()
-> $$ = nterm factor ()
Stack now 0 1
Entering state 8
Reading a token: Next token is token '-' ()
Reducing stack by rule 4 (line 16):
$1 = nterm factor ()
-> $$ = nterm exp ()
Stack now 0 1
Entering state 7
Next token is token '-' ()
Shifting token '-' ()
Entering state 14
Reading a token: Next token is token NUMBER ()
Shifting token NUMBER ()
Entering state 3
Reducing stack by rule 10 (line 22):
$1 = token NUMBER ()
-> $$ = nterm term ()
Stack now 0 1 7 14
Entering state 9
Reducing stack by rule 7 (line 19):
$1 = nterm term ()
-> $$ = nterm factor ()
Stack now 0 1 7 14
Entering state 18
Reading a token: Next token is token '*' ()
Shifting token '*' ()
Entering state 15
Reading a token: Next token is token NUMBER ()
Shifting token NUMBER ()
Entering state 3
Reducing stack by rule 10 (line 22):
$1 = token NUMBER ()
-> $$ = nterm term ()
Stack now 0 1 7 14 18 15
Entering state 19
Reducing stack by rule 8 (line 20):
$1 = nterm factor ()
$2 = token '*' ()
$3 = nterm term ()
-> $$ = nterm factor ()
Stack now 0 1 7 14
Entering state 18
Reading a token: Next token is token '+' ()
Reducing stack by rule 6 (line 18):
$1 = nterm exp ()
$2 = token '-' ()
$3 = nterm factor ()
-> $$ = nterm exp ()
Stack now 0 1
Entering state 7
Next token is token '+' ()
Shifting token '+' ()
Entering state 13
Reading a token: Next token is token NUMBER ()
Shifting token NUMBER ()
Entering state 3
Reducing stack by rule 10 (line 22):
$1 = token NUMBER ()
-> $$ = nterm term ()
Stack now 0 1 7 13
Entering state 9
Reducing stack by rule 7 (line 19):
$1 = nterm term ()
-> $$ = nterm factor ()
Stack now 0 1 7 13
Entering state 17
Reading a token: Next token is token '\n' ()
Reducing stack by rule 5 (line 17):
$1 = nterm exp ()
$2 = token '+' ()
$3 = nterm factor ()
-> $$ = nterm exp ()
Stack now 0 1
Entering state 7
Next token is token '\n' ()
Shifting token '\n' ()
Entering state 12
Reducing stack by rule 3 (line 15):
$1 = nterm calclist ()
$2 = nterm exp ()
$3 = token '\n' ()
= 10
-> $$ = nterm calclist ()
Stack now 0
Entering state 1
Reading a token: Now at end of input.
Shifting token $end ()
Entering state 2
Stack now 0 1 2
Cleanup: popping token $end ()
Cleanup: popping nterm calclist ()