Lex& Yacc - 语法规则

时间:2012-02-05 04:36:39

标签: grammar yacc lex context-free-grammar

我正在努力学习lex和yacc。

我很难理解如何做语法规则。 我的文件已被定义为:

fd 3x00
bk 100
setc 100
int xy3 fd 10 rt 90
rt

我使用printf输出并打印到文件中的内容如下:

Keyword: fd
Illegal: 3x00
Keyword: bk
Keyword: setc
Number: 100
Keyword: int
Id: xy3
Keyword: fd
Number: 10
Keyword: rt
Number: 90

这是我的lex文件 - 我只会显示其中的一部分,以使这篇文章尽可能小

fd                  {return FD; }

[0-9]+[a-z]+[0-9]+      {}  // this is the illegal entry 3x00
[\r\t\n]+               {}
bk                    {return BK;}
setc                  {return SETC;}
[-+]?[0-9]+           {yyval.ival = atoi(yytext); return NUMBER;}
int                   {fprintf(yyout, "%s\n", yytext);}
xy3                   {fprintf(yyout, "%s\n", yytext);}
fd[0-9]+              {fprintf(yyout, "%s\n", yytext);}

%%

这是我的yacc文件。它不完整,因为我不知道如何完成它。

%{

#include <ctype.h>
#include <stdio.h>

%}

%token NUMBER
%token ID
%token FD
%token BK
%token SETC
%token KEYWORD

%%



%%
main()
{


yyparse()


}

我不确定如何为这些编写语法规则。 我可以为表达式创建自己的名字吗?

任何人都可以帮我一个例子,所以我可以看到如何完成它?

1 个答案:

答案 0 :(得分:0)

规则应该是这样的:

statement: command arg {printf("Keyword: %s\n", $1);};

command: KEYWORD {$$ = $1;}
        |FD {$$ = $1;}
        |BK {$$ = $1;};

arg: NUMBER {printf("Number: %s\n", $1);}
    |ID {printf("Id: %s\n", $1);};

这意味着,您应该以这种方式定义语法规则。按|分隔备用定义,并在{ }块中为每个规则编写所需的操作。使用;完成每个规则。当您引用令牌时,请使用$n,其中n是规则中令牌的位置。可以使用$$来引用规则标头。