用c语言实现n的阶层的词法分析(包含错误检测),电子科大编译实验

 输入文件resource.pas内容如下:

begin
  integer k;
  integer function F(n);
    begin
      integer n;
      if n<=0 then F:=1
      else F:=n*F(n-1)
    end;
  read(m); 
k:=F(m);
  write(k)
end

自行修改内容以检测错误。

输出文件:

1. 二元式文件*.dyd

        二元式形式: 单词符号 种别

2. 错误信息文件*.err

        (1)错误信息格式

            LINE:行号 错误性质

      (2)词法需要报三种错误:

           1.非法字符;   2.冒号不匹配。

           3.标识符长度溢出。

c代码:

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define RESULT "result.dyd"
#define SOURCE "source.pas"
#define ERR "err.err"
# define LINEMAX 50

char* str;
char token[17];
char cha;
int line=0,c;
void myerror(int line,const char * message){
    FILE *result=fopen(ERR,"a+");
    char linec[3];
    itoa(line,linec,10);
    if(result!=NULL){
        fputs("Line ",result);
        fputs(linec,result);
        fputs(": ",result);
        fputs(message,result);
        fputs("\n",result);
    }
    fclose(result);
    token[0]='\0';
    cha =' ';
}
void getcharq(){
    cha =*str;
    str++;
}
void getnbq(){
    while(cha==' ')
    getcharq();
}
int letter(){
    return (cha>='a'&&cha<='z')||(cha>='A'&&cha<='Z');
}
int digit( ){
    return cha*1>47&&cha*1<58;
}
int concat(){
    int i=0;
    while(token[i]!='\0')i++;
    if(i==16) return -1;
    else{
        token[i]=cha;
        token[++i] = '\0';
    }
    return 0;
}
void retract(){
    str--;
    cha=*str;
}
int reserve(){
    if(!strcmp(token, "if")) return 4;
    if(!strcmp(token, "begin")) return 1;
    if(!strcmp(token, "then")) return 5;
    if(!strcmp(token, "else")) return 6;
    if(!strcmp(token, "function")) return 7;
    if(!strcmp(token, "end")) return 2;
    if(!strcmp(token, "read")) return 8;
    if(!strcmp(token, "write")) return 9;
    if(!strcmp(token, "integer")) return 3;
    return -1;
}
void writeFile(char* a,int b){
    char class[3];
    itoa(b,class,10);
    char *tmp=a;
    int len=0;
    while(*tmp!='\0'){tmp++;len++;}
    FILE *result=fopen(RESULT,"a+");
    for(int j=16-len;j>0;j--)
    fputs(" ",result);
    if(result!=NULL){
        fputs(a,result);
        fputs(" ",result);
        fputs(class,result);
        fputs("\n",result);
    }
    fclose(result);
    token[0]='\0';
    cha=' ';
}
void readFile(const char * name){
    FILE *source;
    source = fopen(name , "r");
    fseek( source , 0 , SEEK_END );
    int file_size = ftell( source );
    char *tmp =  (char *)malloc( file_size * sizeof( char ) );
    fseek( source , 0 , SEEK_SET);
    fread( tmp , file_size , sizeof(char) , source);
    str=tmp;
    fclose(source);
}

int main(){
FILE *source= fopen(SOURCE, "r+");
char * tmp;
Newline:
while(fgets(tmp, LINEMAX, source) != NULL)
{
line++;
str=(char *)malloc( LINEMAX * sizeof( char ) );
strcpy(str,tmp);
getcharq();
getnbq();

while(cha!='\n'){
    if(letter()){
        int ok;
    while(letter() || digit()){
        ok=concat();
        if(ok<0){ myerror(line,"token is too long");goto Newline;}
        // 
        getcharq();  
    }
    retract();
     c= reserve();
     if(c==-1) writeFile(token,10);
    else writeFile(token,c);
}
else if (digit()){
    while (digit()){
        concat();
        getcharq();
    }
 retract(); 
 writeFile(token,11);
}
else 
 switch (cha){
    case '=':writeFile("=",12);break;
    case '-':writeFile("-",18);break;
    case '*':writeFile("*",19);break;
    case '(':writeFile("(",20);break;
    case ')':writeFile(")",21);break;
    case ';':writeFile(";",23);break;
    case '<':
          getcharq();
             if (cha = '=')  writeFile("<=", 14);
             else if (cha = '>')  writeFile("<>", 13);
             else{
             retract();writeFile("<", 15);
             }
             break;
    case '>':
        getcharq();
        if (cha= '=') writeFile(">=", 16);
        else {
        retract();
        writeFile(">", 0);
        }
        break;
    case ':':
         getcharq();
         if (cha == '=')
         writeFile(":=",20);
         else {myerror(line,"following letter of ':' is not matched");goto Newline;}
         break;
    default: {myerror(line,"illegal letters");goto Newline;}
 }
    getcharq();
    getnbq();
}

writeFile("EOLN",24);

}
writeFile("EOF",25);

fclose(source);
return 0;
}

ps:本人原创,抄袭后果自负

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值