编译原理课程设计之词法分析器

大三的编译原理课程设计。Pascal词法分析器。现在想想学的什么都又还老师啦!

/*******Pascal词法分析器 1.0版 ********
 ****           作者:Hainucrzay         ******                       
 **** Email: hainucrazy@gmail.com  **
 **** All rights reserved(C) 2005.12   **
 *******************************************/

//pre_define.h

#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <iostream.h>

#define LT 1
#define LE 6
#define EQ 10
#define NE 14
#define GT 15
#define GE 20
#define BH  21    //branch 分号';'
#define CA 22    //comma  逗号','
#define CO  23    //colon  冒号':'
#define MU  24    //multiple 乘号'*'
#define LB  26    //Left bracket'('
#define RB  27    //right backet')'
#define AS  30    //assign :=
#define MI  44    //minus '-'
#define PS  45    //plus  '+'
#define DI  46    //Divid '/'
//用到的结构数组:
struct  keyword{          //符号表
    char*   word;
    int     value;
}keytab[] = {
  "AND",      0,
  "BEGIN", 2,
  "BOOL",  3,  //boolean
  "CASE",  4,
  "CONST", 5,
  "DO",  7, 
  "ELSE",  8,
  "END",  9,
  "FALSE", 11, //false
  "FOR",  12,
  "FUNCTION", 13,
  "IF",  16,
  "INTEGER", 17, //integer
  "LABEL", 18,
  "MOD",  25,
  "NOT",      28,
  "OR",  29,
  "PROCEDURE",31,
  "PROGRAM", 32,
  "TRUE",  37, //true
  "THEN",  38,
  "TYPE",  39,
  "UNTIL", 40,
  "VAR",  41,
  "WHILE", 42,
  "WITH",  43, 
};

//scanner.cpp

#include "pre_define.h"

//字符数组TOKEN,用来依次存放一个单词词文中的各个字符
char TOKEN[20];
char *err1="Identifier Overflowed! /n";
//NKEYS:calculate the number of elements in the keytable[] array
int NKEYS = sizeof keytab/sizeof keytab[0];
int lookup(char *keyword); //二分法查找关键字表


int main(int argc,char *argv[])
{
 FILE *srcfile=NULL;
 int ch;
 int i;     //TOKEN[i]:max(i)=20
 int flag;      //判断搜索函数是否成功返回
 int countid=50;//关键字的类别码已给出,而标识符类别码统一一码
 int countnum=51;//整型数类别码统一一码


 if(argc != 2)
 {
  printf("Usage:%s%s",argv[0]," src-file-name/n");
 }else
 {//1else
  srcfile = fopen(argv[1],"r");
  if(srcfile == NULL)
  {
   printf("Can not open text file /"%s/" !",argv[1]);
  }else
  {//2else
   cout<<endl
    <<"*******Pascal词法分析器 v1.0************/n"
    <<"*******Author:HainuCrazy 李洋***********/n"
    <<"*******StudentNo:2003724035 ************/n"
    <<"******Email:hainucrazy@gmail.com********/n"
    <<endl
    <<"The code of the Program has been splited in TOKEN as Follow:"<<endl
    <<"General style:<TOKEN>    (<serial number>,[property])"<<endl;
   while((ch=fgetc(srcfile)) != EOF)
   {//1while
    if ( isspace(ch) )       // if is a whitespace character
       continue;
    else if(isalpha(ch))  /*it must be a identifier*/
    {//1elseif
     TOKEN[0] = ch;
     ch=fgetc(srcfile);
     i=1;
     while(isalnum(ch)) //an alphanumeric character
     {
      TOKEN[i]=ch; i++;
      ch=fgetc(srcfile);
     }
     if(i<20){
      TOKEN[i]='/0';
      fseek(srcfile,-1,SEEK_CUR); //retract
      if((flag = lookup(TOKEN)) >= 0) //reference to the keywords
       printf("%s/t(%d,-)/n",TOKEN,keytab[flag].value);
      else  //is a Identifier 
       printf("%s/t(%d,%s)/n",TOKEN,countid,TOKEN);
      }
     else printf("%s",err1);
    }//1else if
    else if(isdigit(ch))
    {//2elseif
     TOKEN[0]=ch;
     ch=fgetc(srcfile); i=1;
     while(isdigit(ch)){
      TOKEN[i]=ch; i++;
      ch=fgetc(srcfile);
     }//while
     if(i<20){
      TOKEN[i]='/0';
      fseek(srcfile,-1,SEEK_CUR); //retract
      if('0' == TOKEN[0])
       printf("%s/t(%s)/n","Invalid num",TOKEN);
      //else--0 is the 1st digit num
      else printf("%s/t(%d,%s)/n",TOKEN,countnum,TOKEN);
     }
     else printf("%s",err1);
    }//2elseif
    else
     switch(ch)
     {
      case '<': ch=fgetc(srcfile);
       if(ch == '=') printf("%s/t(%d,-)/n","<=",LE);
       else if(ch == '>')
        printf("%s/t(%d,-)/n","<>",NE);
       else{
        fseek(srcfile,-1,SEEK_CUR); //retract
        printf("%c/t(%d,-)/n",'<',LT);
       }
       break;
      case ':': ch=fgetc(srcfile);
       if(ch == '=') printf("%s/t(%d,-)/n",":=",AS);
       else{
        fseek(srcfile,-1,SEEK_CUR);
        printf("%c/t(%d,-)/n",':',CO);
       }
       break;
      case '>': ch=fgetc(srcfile);
       if(ch == '=') printf("%s/t(%d,-)/n","GE");
       else
       {
        fseek(srcfile,-1,SEEK_CUR);
        printf("%c/t(%d,-)/n",'>',GT);
       }
       break;
      case '=': printf("%c/t(%d,-)/n",'=',EQ); break;
      case ';': printf("%c/t(%d,-)/n",';',BH); break;
      case ',': printf("%c/t(%d,-)/n",',',CA); break;
      case '(': printf("%c/t(%d,-)/n",'(',LB); break;
      case ')': printf("%c/t(%d,-)/n",')',RB); break;
      case '-': printf("%c/t(%d,-)/n",'-',MI); break;
      case '+': printf("%c/t(%d,-)/n",'+',PS); break;
      case '*': printf("%c/t(%d,-)/n",'*',MU); break;
      case '/': printf("%c/t(%d,-)/n",'/',DI); break;
      default: printf("symbol ( %c ) not defined yet/n",ch);
       break;
     }//switch
   }//1while
  }//2else
 }//1else
 fclose(srcfile);
 return 1;
}

 

int lookup(char *keyword)

{

       int low = 0, high = NKEYS - 1, mid;
    int Rtnval;
       while (low <= high){
     mid = (low+high)/2;
   
     /*int StrCmp(LPCTSTR lpStr1,
   *   LPCTSTR lpStr2);
   *Returns zero if the strings are identical.
   */
           if((Rtnval=strcmp(keyword,keytab[mid].word)) == 0) return mid;
     else if (Rtnval > 0)  /*Returns a positive value if the       */
    low = mid + 1;  /*string pointed to by lpStr1 is greater*/
         /*than that pointed to by lpStr2.       */
       
        else high = mid - 1; /*Returns a negetive value if the  */
        /*string pointed to by lpStr1 is less*/
        /*than that pointed to by lpStr2.  */
       }
       return -1;

}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值