lex yacc 入门教程(2)

声明:原创作品,转载注明出处:http://www.cnblogs.com/vestinfo/

六、flex和bison相结合。

test.l

test.y

 

编译:

lex yacc 入门教程(2)_第1张图片

 

 

七、文件信息分析。

tset.l分析test.txt文件中的关键词(即test.y中的token标记),遇到token返回给test.y,test.y判断

是否符合一定语法,符合则进行相应动作。

test.l

 

test.y

%{
#include <stdio.h> 
#include <stdlib.h>
typedef char* string;
#define YYSTYPE string
%}
%token NAME EQ AGE
%%
file : record file
    | record
;
record : NAME EQ AGE {
                printf("%s is %s years old!!!\n", $1, $3); }
;
%%
int main()
{
    extern FILE* yyin;
    if(!(yyin = fopen("test.txt", "r")))
    {
        perror("cannot open parsefile:");
        return -1;
    }   
    yyparse();
    fclose(yyin);
    return 0;
}
int yyerror(char *msg)
{
    printf("Error encountered: %s \n", msg);
}

 

test.txt

编译

lex yacc 入门教程(2)_第2张图片

八、token定义的标记的类型及union的使用。

token定义的标记的类型默认为int 且 默认赋值从258开始。如上面的例子,在生成的头文件

test.tab.h中有如下预编译,

/* Tokens.  */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
   /* Put the tokens into the symbol table, so that GDB and other debuggers
      know about them.  */
   enum yytokentype {
     NAME = 258,
     EQ = 259,
     AGE = 260
   };
#endif

如果想将token标记定义为其他类型呢?首先将类型定义在联合中,

%union {
   char *str;
   int  num;
   struct { int num1; int num2; } dnum;
}

然后,如下定义,

%token <str> K_HOST K_ERROR
%token <str> WORD PATH STRING
%token <num> NUM 
%token <dnum> DNUM

 

 

 

补充 :$$ $1 $2….

Each symbol in a bison rule has a value; the value of the target symbol (the one to the
left of the colon) is called $$ in the action code, and the values on the right are numbered
$1, $2, and so forth, up to the number of symbols in the rule.

$$——表示冒号的左边符号;$1——冒号右边第一个;$2——冒号右边第二个,依此类推。

如record : NAME EQ AGE { printf("%s is %s years old!!!\n", $1, $3); } ;

匹配NAME EQ AGE后,$1即NAME所表示的内容,$3即AGE所表示的内容。

你可能感兴趣的:(入门)