Flex和Bison如何找到命令的深度级别
我在Bison中遇到了大问题 - 我需要在if语句中查找命令(P)的最大深度级别。所以我将它编码为language.l(FLEX)
%{
#include "jazyk.tab.h"
int max = 0;
int j = 0;
%}
%%
[ t]+
[Bb][Ee][Gg][Ii][Nn] return(LBEGIN);
[Ee][Nn][Dd] return(LEND);
[Ii][Ff] {j++; if(j>max)max=j; return(LIF);}
[Tt][Hh][Ee][Nn] return(LTHEN);
// command to find max depth level in If statement
[Pp] return(LP);
// V is statement
[Vv] return(LV);
[.] return(.);
[;] return(;);
[-+&~|^/%*(),!] { printf("unknown character in input: %cn", *yytext);}
[n] yyterminate();
%%
void maximum()
{
printf("Maximum depth level of command(P): %in", max);
}
而这对于language.y(BISON)
%{
#include <stdio.h>
#define YYSTYPE float
void koniec(YYSTYPE);
extern char *yytext;
int counterIf;
int counterP;
%}
// define the "terminal symbol" token types (in CAPS by convention)
%token LBEGIN
%token LEND
%token LIF
%token LTHEN
%token LP
%token LV
%token .
%token ;
%start PROGRAM
%%
// the first rule defined is the highest-level rule
PROGRAM: LBEGIN prikazy LEND .
prikazy: prikaz ; prikazy
prikaz: LIF LV LTHEN prikaz {counterIf++;}
prikaz:
prikaz: LP
%%
int main() {
counterIf = 0;
counterP = 0;
printf("Examples to better copy in console: n");
printf("begin p; p; end. n");
printf("begin if v then p; end.n");
printf("begin p; if v then if v then p; p; end.n");
printf("n");
if (yyparse()==0){
printf("Sucesfull n");
printf("If counter: n");
printf("%d n", counterIf);
printf("Maximal depth level of command(P): n");
printf("%d n", counterP);
maximum();
}
else
printf("Wrong n");
}
例如功能 - 当我写入begin if v then p; end.
begin if v then p; end.
结果必须是:IF:1; P:2的最大深度级别; 要么:
begin
p;
if v then
if v then p;
p;
end.
结果:IF:2; 最大深度:3;
我现在真的很绝望。 请用深度计数器帮助我:-((并非所有的英文都是对不起)
不要试图计算扫描仪的深度。 扫描仪不知道程序的结构。 解析器理解嵌套,所以它是你应该计算深度的地方。
由于您目前没有使用语义值进行任何操作,因此我冒昧地将它们用于统计。 如果您有真正的语义值,则可以将统计结构添加为成员,或使用位置值。
当解析器遇到if
语句时,它知道还有一个if
语句,并且当前的嵌套深度比if
的目标的嵌套深度多一个。
我为块添加了if
语句的语法,因为它很简单,并且使程序更有趣。 当解析器增加了一个语句块,它需要总结当前if
算上为块和if
新的语句数,并计算最大深度为最大的两个深度的。 函数merge_statistics
做到这一点。
我不太了解你的嵌套深度应该是多少; 有可能{0, 0}
应该是{0, 1}
。 (在空块的情况下,我认为嵌套深度为0,因为没有语句,但可能甚至不允许空块。)
你需要编译一个理解C99的编译器(如果你使用gcc, -std=c99
或-std=c11
),因为我使用了复合文字。
我也从扫描仪中删除了yyterminate
调用并修复它,以便它坚持令牌之间的空间,虽然也许你不关心它。
扫描器
%option noinput nounput noyywrap yylineno nodefault
%{
#include "jazyk.tab.h"
%}
%%
[[:space:]]+
[Bb][Ee][Gg][Ii][Nn] return(LBEGIN);
[Ee][Nn][Dd] return(LEND);
[Ii][Ff] return(LIF);
[Tt][Hh][Ee][Nn] return(LTHEN);
[Pp] return(LP);
[Vv] return(LV);
[[:alpha:]]+ { printf("Unknown token: %sn", yytext); }
[.;] return(*yytext);
. { printf("unknown character in input: %cn", *yytext);}
解析器
%{
#include <stdio.h>
typedef struct statistics {
int if_count;
int max_depth;
} statistics;
statistics merge_statistics(statistics a, statistics b) {
return (statistics){a.if_count + b.if_count,
a.max_depth > b.max_depth ? a.max_depth : b.max_depth};
}
#define YYSTYPE statistics
extern int yylineno;
int yylex();
void yyerror(const char* message);
%}
%token LIF "if" LTHEN "then" LBEGIN "begin" LEND "end"
%token LV
%token LP
%start program
%%
program: block '.' { printf("If count: %d, max depth: %dn",
$1.if_count, $1.max_depth); }
block: "begin" statements "end" { $$ = $2; }
statements: /* empty */ { $$ = (statistics){0, 0}; }
| statements statement ';' { $$ = merge_statistics($1, $2); }
statement : LP { $$ = (statistics){0, 1}; }
| block
| "if" LV "then" statement { $$ = (statistics){$4.if_count + 1,
$4.max_depth + 1}; }
%%
void yyerror(const char* message) {
printf("At %d: %sn", yylineno, message);
}
int main(int argc, char** argv) {
int status = yyparse();
/* Unnecessary because yyerror will print an error message */
if (status != 0) printf("Parse failedn");
return status;
}
测试运行:
$ ./jazyk <<<'begin if v then p; end.'
If count: 1, max depth: 2
$ ./jazyk <<<'begin p; if v then if v then p; p; end.'
If count: 2, max depth: 3
$ ./jazyk <<<'begin if v then begin if v then p; p; end; end.'
If count: 2, max depth: 3
$ ./jazyk <<<'begin if v then begin p; if v then p; end; end.'
If count: 2, max depth: 3
$ ./jazyk <<<'begin if v then begin if v then p; if v then p; end; end.'
If count: 3, max depth: 3
链接地址: http://www.djcxy.com/p/41751.html