Lex and Yacc

 This is a simple sample how Lex and Yacc cowork.

  • 1) The agreement is Yacc gets tokens by calling a function called yylex(). We define Yacc's yylex() to be static who just calls Lex' getToken(). Lex will generate "#define yylex cminuslex" while cminuslex() is the real working function. So in Lex' getToken(), it really goes into cminuslex().
  • 2) YYSTYPE is the type for $1(the first item right after :), $2.... We define it to be (TreeNode *). So all $1, $2 have the type (TreeNode *).

 

Lex file – cminus.l
Yacc file – cminus.y
%{ 

#include "cminus.tab.h" 

#include "globals.h" 

#include "scan.h" 

// lexeme of identifier or reserved word

char tokenString[MAXTOKENLEN+1]; 

%} 
 
digit       [0-9] 
number      {digit}+ 
letter      [a-zA-Z] 
identifier {letter}+ 
newline     \n|\r\n 
whitespace [ \t]+ 
 

%option nounistd 

 
%% 
 
"if"            {return IF_YY;} 
...... 
{number}        {return NUM_YY;} 
{identifier}    {return ID_YY;} 
{newline}       {g_lineno++;} 
{whitespace}    {/* skip whitespace */} 

"//".*{newline} {g_lineno++;} 

.               {return ERROR_YY;} 
 
%% 

// Token values IF_YY... are exported from 

// Yacc defined as enum or macro. We can 

// only assume it is an int. 

TokenType_YY getToken(void) 

 TokenType_YY currentToken; 
 
 // Calls into Lex' yylex, not Yacc's. 
 currentToken = yylex(); 
 strncpy(tokenString,yytext,MAXTOKENLEN); 
  
 return currentToken; 

int yywrap() 

   return 1; 
}
%{ 

#include "globals.h" 

#include "util.h" 

#include "scan.h" 

#include "parse.h" 

 

#define YYSTYPE TreeNode * 

static char * savedString;

static int savedLineNo; 

static int savedNum; 

// stores syntax tree for main program 

static TreeNode *savedTree;  

 

static int yylex(void); 

 
%} 
 

%token IF_YY ELSE_YY RETURN_YY ...

...... 

%token ERROR_YY 

 

%% // Grammar for Cminus 

 

program : declaration_list

          { savedTree = $1; } 
        ; 
...... 
 
%% 
 

int yyerror(char * message) 

   fprintf(g_listing,

         "Syntax error at line %d: %s\n", 

         g_lineno,message); 

   fprintf(g_listing,"Current token: "); 

   printToken(yychar,tokenString); 
   g_error = TRUE; 
   return 0; 
 

// Calls Lex's getToken(). 

static int yylex(void) 

   return getToken(); 
 

TreeNode * parse(void) 

   yyparse(); 
   return savedTree; 
}

 

 

你可能感兴趣的:(职场,休闲,yacc,Lex,Cminus)