在Yacc語法中,可以允許在規則定義之間插入語法動作,稱為嵌入式動作。
我們直接來看看下面的例子
// ex1: general
thing:
A PRINT B;
PRINT:
{
printf("Function A is finished! Will do function B.");
}
// ex2: embedded action
thing:
A { printf("Function A is finished! Will do function B."); } B
在例子1中,我們將A跟B語法間設定一個空的規則,並將其命名為PRINT。當A語法匹配且相對的A動作執行完成時,便會執行PRINT語法的匹配。因為PRINT是一個空白規則,所以會直接視為匹配成功,便接著執行PRINT動作。最後,編譯器會繼續進行B語法的匹配。
在例子2中,在A跟B之間的PRINT即為嵌入式動作。當讀取到的字串匹配A語法並執行完A動作後,便繼續執行B動作,最後再匹配B語法。
以上兩個做法是等價的。
最後,嵌入式動作在相對位置中也屬於一個項目,因此,相對位置中的參數如下
thing:
A // $1
{ printf("Function A is finished! Will do function B.");} // $2
B // $3
給定一個檔案,內有一個不等式(大於或小於)。請分別計算出左式與右式的值,並判斷該不等式是否正確。
%{
#include "main.h"
#include "yacc.tab.h"
%}
integer (-?([0-9]+))
float (-?([0-9]*\.?[0-9]+))
blank_chars ([ \f\r\t\v]+)
expressions ([-+*/()])
comparison ([<>])
%%
{integer} { sscanf(yytext, "%d", &(yylval.intNum)); return INTEGER; }
{float} { sscanf(yytext, "%f", &(yylval.floatNum)); return FLOAT; }
{expressions} { return yytext[0]; }
{blank_chars} { ; }
{comparison} { return yytext[0]; }
"=" { return yytext[0]; }
\n { ; }
%%
int yywrap(void) {
return 1;
}
%{
#include "main.h"
void yyerror(const char *s);
extern int yylex();
extern int yyparse();
%}
%union {
float floatNum;
int intNum;
}
%token <intNum> INTEGER
%token <floatNum> FLOAT
%type <floatNum> value expr
%left '+' '-'
%left '*' '/'
%right UMINUS
%%
func:
expr
{
printf("Left: %f\n", $1);
}
'>' expr
{ printf("Right: %f\n", $4);
if ($1 > $4)
printf("Result: true\n");
else
printf("Result: false\n");
}
;
expr:
value { $$ = $1; }
| expr '+' expr { $$ = $1 + $3; }
| expr '-' expr { $$ = $1 - $3; }
| expr '*' expr { $$ = $1 * $3; }
| expr '/' expr
{
if ($3 == 0.0) {
yyerror("Error: divisor cannot be zero!");
YYABORT;
} else {
$$ = $1 / $3;
}
}
| '-' expr %prec UMINUS { $$ = -$2; }
| '(' expr ')' { $$ = $2; }
;
value:
FLOAT { $$ = $1; }
| INTEGER { $$ = (float)$1; }
;
%%
void yyerror(const char *s) {
cerr << s << endl;
}
45 + 24 / 3 - ( 7 * 2 - 4 ) > 1 + 95 / 5 + ( 22 - 3 ) * 2
Left: 43.000000
Right: 58.000000
Result: false
有了 embedded action 後,便可以一邊匹配規則,一邊執行操作了。