千月星跡

アイをも求めて彷徨っている孤独なヒーロー

原创 解释器的代码....收藏

新一篇: zheng zhe biao da shi  | 旧一篇: 的功能扩张....

 

这个是书上的例子,

 

%{
#include <stdio.h>
#include <stdlib.h>
#define STRSIZE 
64
#include 
"y.tab.h"
#include 
"intall.h"
extern void lexerror()
;
int strcnt = 0;
char string[STRSIZE + 1] ={0};
%}
%start STR1 COMM
%%
<INITIAL>
"+"    {return(ADDOP);}
<INITIAL>"-"    {return(SUBOP);}
<INITIAL>"*"    {return(MULOP);}
<INITIAL>"/"    {return(DIVOP);}

<INITIAL>
"="    {return(ASGNOP);}
<INITIAL>"=="    {return(EQOP);}
<INITIAL>">"    {return(GTOP);}
<INITIAL>">="    {return(GEOP);}
<INITIAL>"<"    {return(LSOP);}
<INITIAL>"<="    {return(LEOP);}
<INITIAL>"!="    {return(NTOP);}

<INITIAL>
"{"    {return(LC);}
<INITIAL>"}"    {return(RC);}
<INITIAL>"("    {return(LP);}
<INITIAL>")"    {return(RP);}
<INITIAL>";"    {return(SM);}
<INITIAL>","    {return(CM);}
<INITIAL>"        {
                strcnt = 0;
                BEGIN STR1;
                }
<INITIAL>
"/*"    BEGIN COMM;
<INITIAL>if     {return(IF);}
<INITIAL>else   {return(ELSE);}
<INITIAL>while  {return(WHILE);}
<INITIAL>put    {return(PUT);}
<INITIAL>get    {return(GET);}
<INITIAL>[a-z]    {
                yylval.idno = yytext[0] -'a';
                return(IDENT);
                }
<INITIAL>[0-9]+ {
                yylval.num = atoi((char*)yytext);
                return(NUMBER);
                }
<INITIAL>[ ] ;
<INITIAL>[a-z0-9]+ {lexerror(
"word invalid");}
<INITIAL>.        {lexerror(
"character invalid");}
<STR1>
"            {
                if (strcnt>
=STRSIZE)lexerror("string too long");
                string[strcnt]    = '0';
                yylval.addr = pool(string);            
                BEGIN INITIAL;
                return(STRING);
                }
<STR1>\
"        {
                if (strcnt < STRSIZE)
                    string[strcnt++] = '
"';
                }
<STR1>\n        {
                if (strcnt < STRSIZE)
                    string
[strcnt++] = ' ';                 
                }
<STR1>          {
                lexerror(
"string not closed");
                string[strcnt] = '0';
                yylval.addr = pool(string);
                BEGIN INITIAL;
                return(STRING);
                }
<STR1>.            {
                if (strcnt <STRSIZE)string
[strcnt++] = yytext[0];
                }
<COMM>
"*/"        {
                BEGIN INITIAL
;    
                }
<COMM>         
;
<COMM>.            ;
%%
void lexerror(char *s)
{
  extern int yynerrs
, yylineno;
  ++yynerrs;
  fprintf(stderr,"%d:%s ",yylineno,s);
}

 

 

这个文件应该多留心 字符串和注释的写法

 

%{
#include 
<stdio.h>
#include 
"intall.h"
#define ID        100
#define NUM       101
#define STR          102
#define NODESIZE  100

int nodecnt = 0;
struct node{
  
int ntype;
  
int nvalue;
  
struct node *left;
  
struct node *right;
}
nodearea[NODESIZE] = {0};
%}

%union{
  
int idno;
  
int num;
  
int addr;
  
int label;
  
struct node *nodep;
}


%token <idno> IDENT
%token <num>  NUMBER
%token <addr> STRING
%token IF ELSE WHILE GET PUT
%token LP RP
%token LC RC
%token CM SM
%token ASGNOP
%token EQOP GTOP GEOP LSOP LEOP NTOP
%left  ADDOP SUBOP
%left  MULOP DIVOP
%right MINUS
%type  <label> if.prefix while.prefix
%type  <nodep> expr cond
%%
s        :stmt.list
        ;
stmt.list
        :
/*empty*/
        
|stmt.list stmt
        ;
stmt    :IDENT ASGNOP expr SM
            
{
            genexpr($
3);
            clearnode();
            gencode(OP_POP, $
1);
            }

        
|if.prefix stmt
            
{gencode(OP_LBL,$1);}
        
|if.prefix stmt    ELSE 
            
{
            gencode(OP_JMP, $
<label>= newlbl());
            gencode(OP_LBL,$
1);
            }

        stmt
            
{gencode(OP_LBL, $<label>$);}
        
|while.prefix 
            
{
            gencode(OP_JPF, $
<label>4 = newlbl());
            }

        stmt
            
{
            gencode(OP_JMP, $
1);
            gencode(OP_LBL, $
<label>2);
            }

        
|PUT LP put.list RP SM
        
|GET LP IDENT RP SM
            
{gencode(OP_GET,$3);}
        
|LC stmt.list RC
        
|SM
        
|error SM
            
{//可以使用一?机制来?制解析器相信??已?被完全修?了
            yyerrok;
            clearnode();
            }

        
|error RC
            
{
            yyerrok;
            clearnode();
            }

        ;
if.prefix
        :IF LP cond RP
        
{
        genexpr($
3);
        clearnode();
        gencode(OP_JPF,$$ 
= newlbl());
        }

        ;
while.prefix
        :WHILE LP cond RP
        
{
        gencode(OP_LBL,$$ 
= newlbl());
        genexpr($
3);
        clearnode();
        }
 
        ;
put.list
        :id.num.or.str
        
|put.list CM id.num.or.str
        ;
id.num.or.str
        :IDENT
            
{gencode(OP_PUTI, $1);}
        
|NUMBER
            
{gencode(OP_PUTN, $1);}
        
|STRING
            
{gencode(OP_PUTS, $1);}
        ;
cond    :expr EQOP expr
            
{$$ = makeexpr(EQ, $1, $3);}
        
|expr GTOP expr
            
{$$ = makeexpr(GT, $1, $3);}
        
|expr GEOP expr
            
{$$ = makeexpr(GE, $1, $3);}
        
|expr LSOP expr
            
{$$ = makeexpr(LS, $1, $3);}
        
|expr LEOP expr
            
{$$ = makeexpr(LE, $1, $3);}
        
|expr NTOP expr
            
{$$ = makeexpr(NT, $1, $3);}
        ;
expr    :expr ADDOP expr
            
{$$ = makeexpr(ADD, $1, $3);}
        
|expr SUBOP expr
            
{$$ = makeexpr(SUB, $1, $3);}
        
|expr MULOP expr
            
{$$ = makeexpr(MUL, $1, $3);}
        
|expr DIVOP expr
            
{$$ = makeexpr(DIV, $1, $3);}
        
|SUBOP expr   %prec MINUS
            
{$$ = makeexpr(MIN, $20);}
        
|LP expr RP
            
{$$ = $2;}
        
|IDENT
            
{$$ = makenode(ID, $1);}
        
|NUMBER
            
{$$ = makenode(NUM, $1);}
        ;
%%
int yyerror(char *str){
    printf(
"%s ", str);
}


void clearnode()
{
    nodecnt 
= 0;
}


struct node *getnode()
{
    
if (nodecnt > NODESIZE){
        fatal(
"nodearea overflow");    
    }

    
return (&nodearea[nodecnt++]);
}


struct node *makenode(int type , int value)
{
    
struct node *p;
    
    p 
= getnode();
    p
->ntype = type;
    p
->nvalue = value;
    p
->left = NULL;
    p
->right = NULL;
    
return(p);
}


struct node *makeexpr(int type, struct node *left, struct node* right)
{
    
struct node *p;
    
    p 
= makenode(type ,0);
    p
->left = left;
    p
->right = right;
    
    
return(p);
}

/*式のとリーから中間コードを生成する*/
void genexpr(struct node* p)
{
    
if(p == NULL){
        
return;
    }

    
if(p->left){
   &nbs