编译原理及实践教材TINY编译器代码解析

    编译原理及实践教材附带了TINY编译器,在这里对这个小型编译器的代码,做一下简单的解析.

   TINY编译器的词法分析Lex源程序是:

%{

#include "globals.h"

#include "util.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

whitespace  [ /t]+

%%

"if"            {return IF;}

"then"          {return THEN;}

"else"          {return ELSE;}

"end"           {return END;}

"repeat"        {return REPEAT;}

"until"         {return UNTIL;}

"read"          {return READ;}

"write"         {return WRITE;}

":="            {return ASSIGN;}

"="             {return EQ;}

"<"             {return LT;}

"+"             {return PLUS;}

"-"             {return MINUS;}

"*"             {return TIMES;}

"/"             {return OVER;}

"("             {return LPAREN;}

")"             {return RPAREN;}

";"             {return SEMI;}

{number}        {return NUM;}

{identifier}    {return ID;}

{newline}       {lineno++;}

{whitespace}    {/* skip whitespace */}

"{"             { char c;

                  do

                  { c = input();

                    if (c == EOF) break;

                    if (c == '/n') lineno++;

                  } while (c != '}');

                }

.               {return ERROR;}

%%

TokenType getToken(void)

{ static int firstTime = TRUE;

  TokenType currentToken;

  if (firstTime)

  { firstTime = FALSE;

    lineno++;

    yyin = source;

    yyout = listing;

  }

  currentToken = yylex();

  strncpy(tokenString,yytext,MAXTOKENLEN);

  if (TraceScan) {

    fprintf(listing,"/t%d: ",lineno);

    printToken(currentToken,tokenString);

  }

  return currentToken;

}

TINY编译器的语法分析Yacc源程序是:

%{

#define YYPARSER /* distinguishes Yacc output from other code files */

#include "globals.h"

#include "util.h"

#include "scan.h"

#include "parse.h"

#define YYSTYPE TreeNode *

static char * savedName; /* for use in assignments */

static int savedLineNo;  /* ditto */

static TreeNode * savedTree; /* stores syntax tree for later return */

%}

%token IF THEN ELSE END REPEAT UNTIL READ WRITE

%token ID NUM

%token ASSIGN EQ LT PLUS MINUS TIMES OVER LPAREN RPAREN SEMI

%token ERROR

 

%% /* Grammar for TINY */

program     : stmt_seq

                 { savedTree = $1;}

            ;

stmt_seq    : stmt_seq SEMI stmt

                 { YYSTYPE t = $1;

                   if (t != NULL)

                   { while (t->sibling != NULL)

                        t = t->sibling;

                     t->sibling = $3;

                     $$ = $1; }

                     else $$ = $3;

                 }

            | stmt  { $$ = $1; }

            ;

stmt        : if_stmt { $$ = $1; }

            | repeat_stmt { $$ = $1; }

            | assign_stmt { $$ = $1; }

            | read_stmt { $$ = $1; }

            | write_stmt { $$ = $1; }

            | error  { $$ = NULL; }

            ;

if_stmt     : IF exp THEN stmt_seq END

                 { $$ = newStmtNode(IfK);

                   $$->child[0] = $2;

                   $$->child[1] = $4;

                 }

            | IF exp THEN stmt_seq ELSE stmt_seq END

                 { $$ = newStmtNode(IfK);

                   $$->child[0] = $2;

                   $$->child[1] = $4;

                   $$->child[2] = $6;

                 }

            ;

repeat_stmt : REPEAT stmt_seq UNTIL exp

                 { $$ = newStmtNode(RepeatK);

                   $$->child[0] = $2;

                   $$->child[1] = $4;

                 }

            ;

assign_stmt : ID { savedName = copyString(tokenString);

                   savedLineNo = lineno; }

              ASSIGN exp

                 { $$ = newStmtNode(AssignK);

                   $$->child[0] = $4;

                   $$->attr.name = savedName;

                   $$->lineno = savedLineNo;

                 }

            ;

read_stmt   : READ ID

                 { $$ = newStmtNode(ReadK);

                   $$->attr.name =

                     copyString(tokenString);

                 }

            ;

write_stmt  : WRITE exp

                 { $$ = newStmtNode(WriteK);

                   $$->child[0] = $2;

                 }

            ;

exp         : simple_exp LT simple_exp

                 { $$ = newExpNode(OpK);

                   $$->child[0] = $1;

                   $$->child[1] = $3;

                   $$->attr.op = LT;

                 }

            | simple_exp EQ simple_exp

                 { $$ = newExpNode(OpK);

                   $$->child[0] = $1;

                   $$->child[1] = $3;

                   $$->attr.op = EQ;

                 }

            | simple_exp { $$ = $1; }

            ;

simple_exp  : simple_exp PLUS term

                 { $$ = newExpNode(OpK);

                   $$->child[0] = $1;

                   $$->child[1] = $3;

                   $$->attr.op = PLUS;

                 }

            | simple_exp MINUS term

                 { $$ = newExpNode(OpK);

                   $$->child[0] = $1;

                   $$->child[1] = $3;

                   $$->attr.op = MINUS;

                 }

            | term { $$ = $1; }

            ;

term        : term TIMES factor

                 { $$ = newExpNode(OpK);

                   $$->child[0] = $1;

                   $$->child[1] = $3;

                   $$->attr.op = TIMES;

                 }

            | term OVER factor

                 { $$ = newExpNode(OpK);

                   $$->child[0] = $1;

                   $$->child[1] = $3;

                   $$->attr.op = OVER;

                 }

            | factor { $$ = $1; }

            ;

factor      : LPAREN exp RPAREN

                 { $$ = $2; }

            | NUM

                 { $$ = newExpNode(ConstK);

                   $$->attr.val = atoi(tokenString);

                 }

            <

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值