0%

语法分析器tips

关键字struct

c++ 的struct 声明变量的时候不需要加struct前缀。在C语言中,实例化一个结构体必须要加上关键字struct。为了避免每次用的时候都要加上struct前缀,可以定义的时候加上typedef。

YACC文件格式

1
2
3
4
5
... definitions ...(%{}%)
%%
... rules ...
%%
... subroutines ...

第一部分包括标志(token)定义和C代码(用“%{”和“%}”括起来)。
如在定义部分定义标志:
%token INTEGER
当运行yacc后,会产生头文件,里面包含该标志的预定义,如:

1
2
3
4
5
#ifndef YYSTYPE 
#define YYSTYPE int
#endif
#define INTEGER 258
extern YYSTYPE yylval;

lex使用该头文件中的标志定义。Yacc调用lex的yylex()来获得标志(token),与标志对应的值由lex放在变量yylval中。

yylyal

Lex 将解析的token保存在yylval中,yylval的类型由YYSTYPE决定,YYSTYPE缺省类型是int。为了保存不同类型的变量,yylval 别定义为union(详情见下面参考部分)。

如果没有指定 \ && 就是指向yylval 本身。

yytext

由于yytext是字符串指针,所以注意要进行深拷贝,否则yytext最后指向},会赋给所有的symbol

参考

If the type is int (the default), you might write this in yylex:

1
2
3
4

yylval = value; /* Put value onto Bison stack. */
return INT; /* Return the type of the token. */

When you are using multiple data types, yylval’s type is a union made from the %union declaration (see The Union Declaration). So when you store a token’s value, you must use the proper member of the union. If the %union declaration looks like this:

1
2
3
4
5
%union {
int intval;
double val;
symrec *tptr;
}

then the code in yylex might look like this:

1
2
3
4

yylval.intval = value; /* Put value onto Bison stack. */
return INT; /* Return the type of the token. */

enum枚举类型

1
enum 枚举名 {枚举元素1,枚举元素2,……};

第一个枚举成员的默认值为整型的 0,后续枚举成员的值在前一个成员上加 1,可以在定义枚举类型时改变枚举元素的值。在C 语言中,枚举类型是被当做 int 或者 unsigned int 类型来处理的。

vs报错

0xC0000005: 读取位置 xxx时发生访问冲突

访问了不该访问的地方。越界了。

VS2017”const char “ 类型的实参与 “char “ 类型的形参不兼容

属性 – C/C++ – 语言 – 符合模式 改为“否”

分不清=和==是要吃大亏的。循环写错了递增条件是要吃大亏的。