Parsing 野牛简易计算器

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

我不熟悉语法分析。以下是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 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
    ,以打印表达式(
    $2
    )的值,而不是没有值的calclist本身

  • 我将单字符标记(
    ADD
    SUB
    等)更改为实际的单字符(
    '+'
    -
    等),以简化扫描仪

  • 我添加了一个简单的lexer

  • 最后,我通过添加
    yydebug=1启用了跟踪
    main
    函数,并使用
    -t
    标志调用bison

使用您提供的表达式,结果如下所示。要了解状态转换,您需要打印状态转换表。使用
-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 ()