yacc细节

1、嵌入式动作在规则内变成一个符号,所以它的值($$)像任何其他的符号一样对于规则末端的动作都是可以用的。

如:

thing: A {$$=17;} B C

{printf(%d"",$2);}

在使用嵌入式动作时,如果正在使用“%union”和有类型的符号值,则在引用动作值时就得将值放入尖括号内,例如将它放入嵌入式动作时的$<type>$,以及在规则末端动作中引用它的$<type>3。

2、明确的符号类型

通过在¥和符号数字之间使用或在2个$之间的尖括号内插入类型名,如$<xxx>3或$<xxx>$,YACC允许为符号值引用声明一个明确的类型。3、标记值

YACC语法分析程序中每个符号都有一个相关的值。在语法分析程序中,一定要声明所有具有值的标记的值类型。

%union声明标识符号值的所有可能的C类型。将拷贝到输出文件的YYSTYPE类型的C联合类型声明中。

4、yyerror()提供错误报告例程

5、YYABORT使得语法分析例程yyparse()以一个非零值立即返回,显示失败

6、YYACCEPT:yyparse()以一个零值返回,显示成功。

7、yyparse()语法分析程序的入口点,成功返回零,失败返回非零

8、YACC的冲突,YACC只能向前看一个标记。如下的没有冲突:tgt

start:x B

|y C;

x: A;

y:A;

9、移进/归约冲突

stmt:if '(' cond')' stmt

|if '(' cond ')' stmt ELSE stmt

if (cond) if (cond) stmt ELSE stmt如何理解

1)if (cond){if (cond) stmt ELSE stmt}

2)if (cond){if (cond) stmt }ELSE stmt

设置明显的优先级阻止YACC发布警告

%nonassoc LOWER_THEN_ELSE或%nonassoc THEN

%nonassoc ELSE

ELSE优先级比LOWER_THEN_ELSE高,因为移进优先级必须高于归约优先级

1、继承的属性

属性以标记值开始,即从语法分析树的叶子开始。每次规则被归约时,信息概念性地在语法分析树中上移。并且它的动作根据规则右侧符号值勤合成符号($$)的值。

例如:

declaration:class type namelist;

class: GLOBAL {$$=1;}

|LOCAL {$$=2;}

;

type:REAL {$$=1;}

|INTEGER {$$=2;}

;

namelist:NAME {mksymbol($0,$-1,$1);}

|namelist NAME {mksymbol($0,$-1,$2);}

yacc允许访问它的左侧的内部堆栈上的符号($0,$-1,$-2....),上例中$0指在namelist产生式的符号之前被堆栈的type的值。$0指class。

继承的符号类型必须在动作代码中采用明确的类型提供类型名。

2、文字块

%{

.....

%}

内容被原封不动地拷贝到生成的C源文件中靠近开头的部分。

3、优先级和结合性

结合性:%left左结合,%right右结合,%nonassoc非结合操作

通过声明结合性的顺序决定优先级,声明在后的优先级高

4、左、右递归,左递归更适合于YACC处理

exprlist:exprlist ','expr;

exprlist:expr ','exprlist;

5、规则尾端有明确的优先级:

expr:expr '*' expr

|expr '-' expr

|'-'expr %prec UMINUS;

6、符号类型

YACC在内部将每个值做为包括所有类型的C联合类型来声明。在%union声明中列出所有的类型,YACC将其转变为称为YYSTYPE的联合类型的类型定义。对于值已在动作代码中设置和使用的符号,必须声明它的类型。对非终结符使用%type(如%type<dval> expression),对标记即终结符使用%token,%left,%right,%nonassoc,(如:%token<dval>REAL)。在使用$$、$1等引用值,YACC会自动使用联合的适当字段。

你可能感兴趣的:(C++,c,C#,嵌入式)