例:简单整型算术表达式文法: exp = exp addop term term addo→+ term - term mulop factor|factor mulot→ factor→(exp)| number 的yacc说明文件如下: 定义部 include <stdio.h> 在输出文件开头 #include <ctype. h> 直接加的代码 Ootoken number 声明记号 9%
例:简单整型算术表达式文法: exp → exp addop term | term addop→ + | - term → term mulop factor | factor mulop → * factor → ( exp ) | number 的yacc说明文件如下: %{ #include <stdio.h> #include <ctype.h> %} %token NUMBER %% 定义部分 在输出文件开头 直接加的代码 声明记号
规则部分 command: exp iprint(%dVn",$1)此处进行了 ;/*打印结果*/ 文法的拓广。 exp -term等=1求3:了口S代表刚识别出 term{$$=$1; 的非终结符的值, (文法规则左边的 term:term* factor{$=车1*$3}符号值) factor i ss 车1; 口s1、$2、$3 faco: NUMBER{$$=车1} 代表文法规则右 (exp )t $=$2 边的第1、2、3. 个符号值。 注:第一条规则的左部为文法的开始符号 也可以用% start文法符号来指定文法的开始符号。 fstart command
command : exp {printf(“%d\n”,$1);} ; /* 打印结果 */ exp : exp ‘+’ term { $$ = $1+$3; } | exp ‘-’ term { $$ = $1-$3; } | term { $$ = $1; } ; term : term ‘*’ factor { $$ = $1*$3; } | factor { $$ = $1; } ; factor : NUMBER { $$ = $1; } | ‘(’ exp ‘)’ { $$ = $2; } ; 规则部分 注:第一条规则的左部为文法的开始符号。 也可以用%start 文法符号来指定文法的开始符号。 %start command 此处进行了 文法的拓广。 ❑$$代表刚识别出 的非终结符的值, (文法规则左边的 符号值)。 ❑$1、$2、$3… 代表文法规则右 边的第1、2、3… 个符号值
% maino i return yyparse0; int yylex(void) i int c; 辅助部分 while((e=getchar) 删除空格 if isdigit(c)( Yac假设记号的值被 ungetc(c, stdin); scanf“0 od”,&yyva); 赋给了由Yac内部定 return NUMBER) 义的变量yyla,且 在识别记号时必须给 In)return 0; /标识分析结束 sylva 赋值 return(c); void yyerror(char*s) fprintf(stderi;”%s”,s): }/打印错误信息*
%% main() { return yyparse(); } int yylex(void) { int c; while((c=getchar())==‘ ’) ; /* 删除空格*/ if ( isdigit(c) ) { ungetc(c, stdin); scanf(“%d”, &yylval); return(NUMBER); } if (c == ‘\n’) return 0; /* 标识分析结束*/ return(c); } void yyerror(char *s) { fprintf(stderr,”%s”,s); } /* 打印错误信息*/ 辅 助 部 分 Yacc假设记号的值被 赋给了由Yacc内部定 义的变量yylval,且 在识别记号时必须给 yylval赋值
2、规则部分 由文法的一组产生式及每一产生式相应的语义动作组成。 对于文法中的每个产生式: A→a1a2|an 相应地写成: A:a1{语义动作1;} a2{语义动作2;} an{语义动作n;};
由文法的一组产生式及每一产生式相应的语义动作组成。 对于文法中的每个产生式: A→α1|α2|…|αn 相应地写成: A:α1 {语义动作1;} | α2 {语义动作2;} … | αn {语义动作n;}; 2、规则部分
口规则部分动作书写为c代码 口在书写动作时,可用Yac伪变量( pseudo variable) 口当识别一个文法规则时,规则中的每个符号都有 个整型值。这些值保存在值栈( value stack)中,可 通过以$开始的伪变量来引用。 B: exp exp+,term $$=S1+$3; 1 表示当识别规则exp→ exp+term时, 将右边的exp值与term值之和赋值给左边的exp
❑规则部分动作书写为c代码 ❑在书写动作时,可用Yacc伪变量(pseudo variable)。 ❑当识别一个文法规则时,规则中的每个符号都有 一个整型值。这些值保存在值栈(value stack)中,可 通过以$开始的伪变量来引用。 例:exp : exp '+' term { $$=$1+$3; } 表示当识别规则exp→exp+term时, 将右边的exp值与term值之和赋值给左边的exp