|
5.5.1 YACC MetalanguageThe YACC metalanguage has a form similar to that for LEX: Definitions <-- C declaration and token definitions> %% Rules <-- BNF plus associated actions> %% User-Written Procedures <-- In C> The Definitions section can contain the typical things found at the top of a C program: constant definitions, structure declarations, include statements, and user variable definitions. Tokens may also be defined here. The Rules section contains the BNF. The left-hand side is separated from the right-hand side by a color, ":". The actions may appear interspersed in the right-hand side; this means they will be executed when all the tokens or nonterminals to the action's left are shifted. If the action occurs after a production, it will be invoked when a reduction ( of the right-hand side to the left-hand side of a production ) is made. Thus, a YACC input file looks like the following:
%{
#include 1
#include 2
#define ...
%}
%token ...
...
%%
Nonterminal: Right-Hand side {semantic action 1}
| Right-hand side {semantic action 2}
...
%%
C functions
Example 6 shows a YACC input file for the language consisting of sequences of assignment statements. EXAMPLE 6 Sequences of assignment statements in YACC
%{
#include <stdio.h>
%}
%start program
%token Id
%token Lit
%%
Program: Statements {printf("Program \n");};
Statements: Statement Statements {printf("Statements \n)";};
| Statement {printf("Statements \n");};
Statement: AsstStmt {printf("Statement \n");};
AsstStmt: Id ":=" Expression {printf("AsstStmt \n");};
Expression: Expression "=" Term {printf("Expression \n");};
| Expression "-" Term {printf("Expression \n");};
| Term {printf("Expression \n");};
Term: Term "*" Factor {printf("Term \n");};
| Term "/" Factor {printf("Term \n");};
| Factor {printf("Term \n");};
Factor: "(" Expression ")" {printf("Factor \n");};
| Id {printf("Factor \n");};
| Lit {printf("Factor \n");};
%%
#include lex.yy.c
main()
{
yyparse ();
}
In Example 6, the lexical analyzer is the one output by LEX, or users may write their own ( and call it "lex.yy.c"). Alternatively, a function called "yylex()", consisting of code to find tokens, could be written in either the definition section or the User-Written Procedures section. YACC contain facilities for specifying precedence and associativity of operators and for specifying errors. An error production in YACC is of the form: B where We will look at this example again in Chapter 6 when we discuss semantic analysis.
|