|
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 error { Action } where is an erroneous construct. We will look at this example again in Chapter 6 when we discuss semantic analysis. Send questions and comments to: Karen Lemone |