输入文件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:本人原创,抄袭后果自负