码迷,mamicode.com
首页 > 编程语言 > 详细

Test语言编译器V1.0

时间:2015-07-03 00:02:01      阅读:417      评论:0      收藏:0      [点我收藏+]

标签:

感觉这个挺好耍的,书上的代码有错误,而且功能有限。

一、词法分析

特点:

(1)可对中文进行识别:
(2)暂不支持负数,可以在读入‘-‘时进行简单标记后就能对简单负数进行识别了。

技术分享
#include <iostream>
#include <cstdio>
#include <cctype>
#include <cstring>
using namespace std;
#define KEYWORDNUM 9     //关键字个数
#define MAXLENGTH 39     //标识符最大长度
#define MAXFILENAME 100  //文件名最大长度

FILE *fin,*fout;
char Scanin[MAXFILENAME],Scanout[MAXFILENAME];
char *keyword[KEYWORDNUM]={"if","else","for","while","do","int","read","write","main"};
char singleword[]="+-*%(){};,:";
char doubleword[]="><=!";
char token[MAXLENGTH+2]; //存放识别单词
int frow,brow;           //符号起止行标记
int i,j,k,es;            //临时整型变量
char ch,ch1;             //临时字符变量

/******************************/
/*       错误列表:
     1 打开输入文件出错
     2 打开输出文件出错
     3 标识符过长
     4 标识符命名不合法       */
/******************************/

int Init()
{
    //printf("请输入源程序文件名(包括路径):\n");
    //scanf("%s", Scanin);
    //printf("请输入词法分析输出文件名(包括路径):\n");
    //scanf("%s", Scanout);
    
    strcpy(Scanin,"C:\\Users\\Administrator\\Desktop\\in.txt");
    strcpy(Scanout,"C:\\Users\\Administrator\\Desktop\\out1.txt");    
    
    if ((fin=fopen(Scanin,"r"))==NULL){
        printf("打开词法分析输入文件出错!\n");
        return 1;
    }
    if ((fout=fopen(Scanout,"w"))==NULL){
        printf("创建词法分析输出文件出错!\n");
        return 2;
    }
    return 0;
}
char getNextChar()
{
    char ch=getc(fin);
    if(ch==\n) frow++;
    return ch;
}
int TESTscan()
{
    frow=brow=1; 
    ch=getNextChar();
    while (ch!=EOF)
    {
        while(ch==  || ch==\n || ch==\t){
            ch=getNextChar();
        }

        brow=frow;
        if (ch==EOF) break;
        
        if (isalpha(ch)){ //字母
            j=0;
            token[j++]=ch;
            bool isLong=false; //超长标记
            ch=getNextChar();
            while (isalnum(ch)){ //字母+数字
                token[j++]=ch;
                ch=getNextChar();
                if (j>MAXLENGTH){
                    isLong=true;
                    while (isalnum(ch)){ //超长,自动截断
                        ch=getNextChar();
                    }
                }
            }
            token[j]=\0;
            if (isLong==true){ //标识符太长
                es=3;
                printf("ERROR(%d): 标识符\"%s\"超长\n",brow,token);
                fprintf(fout,"%d\t%s\t%s\n",brow,"ERROR",token);
                continue;
            }
            
            k=0;
            char str[MAXLENGTH+2];
            for (i=0;i<strlen(token);i++){ //小写化
                str[i]=tolower(token[i]);
            }
            str[i]=\0;
            while (k<KEYWORDNUM && strcmp(str,keyword[k]))
                k++;
            if (k>=KEYWORDNUM)
                fprintf(fout,"%d\t%s\t%s\n",brow,"ID",token);
            else
                fprintf(fout,"%d\t%s\t%s\n",brow,str,token);
        }
        
        else if (isdigit(ch)){ //数字
            j=0;
            token[j++]=ch;
            ch=getNextChar();
            while (isdigit(ch)){
                token[j++]=ch;
                ch=getNextChar();
            }
            token[j]=\0;
            fprintf(fout,"%d\t%s\t%s\n",brow,"NUM",token);
        }
        
        else if (strchr(singleword,ch)>0){ //单分界符
            token[0]=ch;
            token[1]=\0;
            fprintf(fout,"%d\t%s\t%s\n",brow,token,token);
            ch=getNextChar();
        }
        
        else if (strchr(doubleword,ch)>0){ //双分界符
            token[0]=ch;
            ch=getNextChar();
            if (ch===){
                token[1]=ch;
                token[2]=\0;
                ch=getNextChar();
            }
            else token[1]=\0;
            fprintf(fout,"%d\t%s\t%s\n",brow,token,token);
        }
        
        else if (ch==/){ //注释
            ch=getNextChar();
            if (ch==*){
                ch1=getNextChar();
                do{ //删除注释
                    ch=ch1;
                    ch1=getNextChar();
                } while ((ch!=* || ch1!=/) && ch1!=EOF);
                ch=getNextChar();
            }
            else{
                token[0]=/;
                token[1]=\0;
                fprintf(fout,"%d\t%s\t%s\n",brow,token,token);
            }
        }
        
        else if (ch==\"){ //字符串
            j=0;
            ch=getNextChar();
            while (ch!=\"){
                token[j++]=ch;
                ch=getNextChar();
            }
            token[j]=\0;
            fprintf(fout,"%d\t%s\t%s\n",brow,"STR",token);
            ch=getNextChar();
        }
        
        else{ //命名不规范
            token[0]=ch;
            token[1]=\0;
            if(ch<0){ //中文处理
                ch=getNextChar();
                token[1]=ch;
                token[2]=\0;
            }
            es=4;
            fprintf(fout,"%d\t%s\t%s\n",brow,"ERROR",token);
            printf("ERROR(%d): 符号\"%s\"不规范\n",brow,token);
            ch=getNextChar();
        }
    }
    fprintf(fout,"%d\tEOF\tEOF\n",brow);
    fclose(fin);
    fclose(fout);
    return es;
}
int main()
{
    int es=Init();
    if(!es){
        es=TESTscan();
        if (es>0)
            printf("词法分析有错,编译停止!\n");
        else
            printf("词法分析成功!\n");
    }
    return 0;
}
View Code

 

二、语法分析

特点:

(1)修正书上代码中存在的大量错误

(2)增加对复合语句的处理

(3)支持变量连续定义

(4)支持字符串(可带空白字符)的输出

(5)报错具体到行中的具体位置

(6)无除0报错,首先除0报错不属于语法分析,其次通过改正也只能报5/0这种显式错误,不能报9/(3+2-5)这种错误,因此意义不大

(7)无死循环错误,首先不属于语法分析,其次现在没有一种程序设计语言能报这种错误,循环中可根据条件改变变量的值,是不可预知的

技术分享
#include <stdio.h>
#include <ctype.h>
#include <conio.h>
#include <string.h>
#include <windows.h>

int TESTparse();
int program();
int compound_Stat();
int statement();
int expression_Stat();
int expression();
int bool_expr();
int additive_expr();
int term();
int factor();
int if_stat();
int while_stat();
int for_stat();
int write_stat();
int read_stat();
int do_while_stat();
int declaration_stat();
int declaration_list();
int statement_list();
int compound_stat();
int expression_stat();

#define MAXFILENAME 100  //文件名最大长度
#define MAXLENGTH 40     //字符串最大长度

int wrow;                                      //错误行号
FILE *fin,*fout;                               //输入输出文件的指针
char token[MAXLENGTH],token1[MAXLENGTH];       //token保存单词符号,token1保存单词值
char Scanin[MAXFILENAME],Scanout[MAXFILENAME]; //输入输出文件名

int TESTparse()
{    
    int es=0;
    if ((fin=fopen(Scanin,"r"))==NULL){  
        printf("\n打开%s错误!\n",Scanout);
        es=10;
    }
    
    if ((fout=fopen(Scanout,"w"))==NULL){  
        printf("\n打开%s错误!\n",Scanout);
        es=10;
    }
    
    if (es==0) es=program();
    printf("=====语法分析结果!======\n");
    switch(es)
    {
    case 0: printf("语法分析成功!\n");break;
    case 10:printf("打开文件失败!\n");break;
    case 1: printf("ERROR(%d): \"%s\"前面缺少{\n",wrow,token1);break;
    case 2: printf("ERROR(%d): \"%s\"前面缺少}\n",wrow,token1);break;
    case 3: printf("ERROR(%d): \"%s\"前面缺少标识符\n",wrow,token1);break;
    case 4: printf("ERROR(%d): \"%s\"前面缺少分号\n",wrow,token1);break;
    case 5: printf("ERROR(%d): \"%s\"前面缺少(\n",wrow,token1);break;
    case 6: printf("ERROR(%d): \"%s\"前面缺少)\n",wrow,token1);break;
    case 7: printf("ERROR(%d): \"%s\"前面缺少操作数\n",wrow,token1);break;
    case 9: printf("ERROR(%d): \"%s\"前面缺少主程序\n",wrow,token1);break;
    case 11:printf("ERROR(%d): 主程序名错误!\n",wrow);break;
    case 12:printf("ERROR(%d): \"%s\"前面缺少while\n",wrow,token1);break;
    case 25:printf("ERROR(%d): \"%s\"已超出程序末尾\n",wrow,token1);break;
    case 26:printf("ERROR(%d): else没有匹配的if\n",wrow);
    }
    fclose(fin);
    fclose(fout);
    return es;
}

//<程序>::={<声明序列><语句序列>}
//program::={<declaration_list><statement_list>}
int program()
{
    int es=0;
    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    es=declaration_list(); //声明语句
    if (es>0) return es;

    if (strcmp(token,"main")) return 9; //main区
    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    if (strcmp(token,"ID")) return 11; //程序名
    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    if (strcmp(token,"{")) return 1; //判断是否‘{‘
    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    es=statement_list(); //语句序列
    if (es>0) return es;
    if (strcmp(token,"}")) return 2; //判断是否‘}‘
    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    if (strcmp(token,"EOF")) return 25; //超出程序末尾
    return es;
}

//<声明序列>::=<声明序列><声明语句>|<声明语句>
//<declaration_list>::=<declaration_list><declaration_stat>|<declaration_stat>
int declaration_list()
{
    int es=0;
    while (strcmp(token,"int")==0){
        es=declaration_stat();
        if (es>0) return es;
    }
    return es;
}

//<声明语句>::=int<变量>;
//<declaration_stat>::=int ID;
int declaration_stat()
{
    int es=0;
    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    while (1){ //支持连续定义
        if (strcmp(token,"ID"))    return 3; //不是标识符
        fscanf(fin,"%d %s %s\n",&wrow,token,token1);
        printf("%s %s\n",token,token1);
        if (strcmp(token,",")==0){
            fscanf(fin,"%d %s %s\n",&wrow,token,token1);
            printf("%s %s\n",token,token1);
        }
        else break;
    }
    if (strcmp(token,";") )    return 4; //缺少分号
    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    return es;
}

//<语句序列>::=<语句序列><语句>|<语句>
//<statement_list>::=<statement_list><statement>|<statement>
int statement_list()
{
    int es=0;
    while (strcmp(token,"}")){
        es=statement();
        if (es>0) return es;
        if (strcmp(token,"EOF")==0){
            return 2; //缺少}
        }
    }
    return es;
}

//<语句>::=<if语句>|<while语句>|<for语句>|<read语句>|<write语句>|<复合语句>|<表达式语句>
//<statement>::= <if_stat>|<while_stat>|<for_stat>|<compound_stat>|<expression_stat>
int statement()
{
    int es=0;
    if ((strcmp(token,"if")==0 || strcmp(token,"else")==0)) es=if_stat();//<IF语句>
    else if (strcmp(token,"while")==0) es=while_stat();//<while语句>
    else if (strcmp(token,"for")==0) es=for_stat();//<for语句>
    else if (strcmp(token,"do")==0) es=do_while_stat(); //do_while语句
    else if (strcmp(token,"read")==0) es=read_stat();//<read语句>
    else if (strcmp(token,"write")==0) es=write_stat();//<write语句>
    else if (strcmp(token,"{")==0) es=compound_stat();//<复合语句>
    else if ((strcmp(token,"ID")==0 || strcmp(token,"NUM")==0 || strcmp(token,"(")==0) || strcmp(token,";")==0) es=expression_stat();//<表达式语句>
    return es;
}

//<IF语句>::=if(<表达式>)<语句>[else<语句>]
//<IF_stat>::=if(<expr>)<statement>[else<statement>]
int if_stat()
{
    if (strcmp(token,"else")==0) return 26; //else未匹配if
    int es=0;
    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    if (strcmp(token,"("))     return 5; //缺少左括号
    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    es=expression();
    if (es>0) return es;
    if (strcmp(token,")"))  return 6; //缺少右括号
    
    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    es=statement(); //语句
    if (es>0) return es;
    
    if (strcmp(token,"else")==0){ //else部分处理
        fscanf(fin,"%d %s %s\n",&wrow,token,token1);
        printf("%s %s\n",token,token1);
        es=statement(); 
        if (es>0) return es;
    }
    return es;
}

//<复合语句>::={<语句序列>} 
//<compound_stat>::={<statement_list>} 
int compound_stat()
{
    int es=0;
    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    es=statement_list(); //语句序列
    if (es>0) return es;
    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    return es;
}

// <do_whilie语句>::do{语句序列}while(表达式)
// <do_whilie_stat>::do{statment_list}while(expression)
int do_while_stat()
{
    int es=0;  
    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    if (strcmp(token,"{")) return 1; //缺少左括号
    es=statement(); //语句
    if (es>0) return es;
    printf("%s %s\n",token,token1);
    if(strcmp(token,"while")) return 12; //缺少while
    
    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    if (strcmp(token,"("))  return 5; //缺少左括号
    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);

    es=expression(); //表达式
    if (es>0) return es;
    
    if (strcmp(token,")"))  return 6; //缺少右括号
    if (es>0) return es;
    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    return es;
}

//<while语句>::=while(<表达式>)<语句>
//<while_stat>::=while(<expr>)<statement >
int while_stat()
{
    int es=0;
    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    if (strcmp(token,"("))  return 5; //缺少左括号
    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    es=expression();
    if (es>0) return es;
    if (strcmp(token,")"))  return 6; //缺少右括号

    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    es=statement();
    if (es>0) return es;
    return es;
}

//<for语句>::=for(<表达式>;<表达式>;<表达式>)<语句>
//<for_stat>::=for(<expr>,<expr>,<expr>)<statement>
//<for_stat>::=for (<expression>;
int for_stat()
{
    int es=0; 
    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    if (strcmp(token,"("))  return 5; //缺少左括号
    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    es=expression();
    if (es>0) return es;
    if (strcmp(token,";"))     return 4; //缺少分号
    
    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    es=expression();
    if (es>0) return es;
    if (strcmp(token,";"))  return 4; //缺少分号
    
    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    es=expression();
    if (es>0) return es;
    if (strcmp(token,")"))  return 6; //缺少右括号

    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    es=statement();
    if (es>0) return es;
    return es;
}

//<read_语句>::=read<变量>;
//<read_stat>::=read ID;
int read_stat()
{
    int es=0;
    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    if (strcmp(token,"ID"))  return 3; //缺少标识符

    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    if (strcmp(token,";"))  return 4; //缺少分号
    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    return es;
}

//<write_语句>::=write <表达式>;
//<write_stat>::=write <expression>;
//<write_STR>::write <STR>;
int write_stat()
{
    int es=0;
    fscanf(fin,"%d %s ",&wrow,token);
    printf("%s ",token);
    if (strcmp(token,"STR")==0){ //输出字符串
        fgets(token1,1024,fin);
        printf("%s",token1);
        fscanf(fin,"%d %s %s\n",&wrow,token,token1);
        printf("%s %s\n",token,token1);
        if (strcmp(token,";"))  return 4; //缺少分号
        fscanf(fin,"%d %s %s\n",&wrow,token,token1);
        printf("%s %s\n",token,token1);
        return es;
    }
    fscanf(fin,"%s",&token1);
    printf("%s\n",token1);
    es=expression();
    if (es>0) return es;
    if (strcmp(token,";"))  return 4; //缺少分号
    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    return es;
}

//<表达式语句>::=<<表达式>;|;
//<expression_stat>::=<expression>;|;
int expression_stat()
{
    int es=0;
    if (strcmp(token,";")==0){
        fscanf(fin,"%d %s %s\n",&wrow,token,token1);
        printf("%s %s\n",token,token1);
        return es;
    }
    es=expression();
    if (es>0) return es;
    if (strcmp(token,";")==0){
        fscanf(fin,"%d %s %s\n",&wrow,token,token1);
        printf("%s %s\n",token,token1);
        return es;
    }
    else{
        return 4; //缺少分号
    }
}

//<表达式>::=<标识符>=<布尔表达式>|<布尔表达式>
//<expr>::=ID=<bool_expr>|<bool_expr>
int expression()
{
    int es=0,fileadd;
    char token2[MAXLENGTH+2],token3[MAXLENGTH+2];
    if (strcmp(token,"ID")==0){
        fileadd=ftell(fin); //记住当前文件位置
        fscanf(fin,"%d %s %s\n",&wrow,token2,token3);
        printf("%s %s\n",token2,token3);

        if (strcmp(token2,"=")==0){ //‘=‘
            fscanf(fin,"%d %s %s\n",&wrow,token,token1);
            printf("%s %s\n",token,token1);
            es=bool_expr();
            if (es>0) return es;
        }
        else{ //"=="
            fseek(fin,fileadd,0); //若非‘=‘则文件指针回到‘=‘前的标识符
            es=bool_expr();
            if (es>0) return es;
        }
    }
    else{
        es=bool_expr();
    }
    return es;
}

//<布尔表达式>::=<算术表达式>|<算术表达式>(>|<|>=|<=|==|!=)<算术表达式>
//<bool_expr>::=<additive_expr>|< additive_expr >(>|<|>=|<=|==|!=)< additive_expr >
int bool_expr()
{
    int es=0;
    es=additive_expr();
    if (es>0) return es;
    if (strcmp(token,">")==0 || strcmp(token,">=")==0 || strcmp(token,"<")==0 || 
        strcmp(token,"<=")==0 || strcmp(token,"==")==0 || strcmp(token,"!=")==0){
        char token2[MAXLENGTH+2];
        strcpy(token2,token); //保存运算符
        fscanf(fin,"%d %s %s\n",&wrow,token,token1);
        printf("%s %s\n",token,token1);
        es=additive_expr();
        if (es>0) return es;
    }
    return es;
}

//<算术表达式>::=<项>{(+|-)<项>}
//<additive_expr>::=<term>{(+|-)< term >} 
//< additive_expr>::=<term>{(+< term >@ADD |-<项>@SUB)}
int additive_expr()
{
    int es=0;
    es=term();
    if (es>0) return es;
    while (strcmp(token,"+")==0 || strcmp(token,"-")==0){
        char token2[MAXLENGTH+2];
        strcpy(token2,token);
        fscanf(fin,"%d %s %s\n",&wrow,token,token1);
        printf("%s %s\n",token,token1);
        es=term();
        if (es>0) return es;
    }
    return es;
}

//<项>::=<因子>{(*|/)<因子>}
//< term >::=<factor>{(*| /)< factor >} 
//< term >::=<factor>{(*< factor >@MULT | /< factor >@DIV)} 
int term()
{
    int es=0;
    es=factor();
    if (es>0) return es;
    while (strcmp(token,"*")==0 || strcmp(token,"/")==0  || strcmp(token,"%")==0){
        char token2[MAXLENGTH+2];
        strcpy(token2,token);
        fscanf(fin,"%d %s %s\n",&wrow,token,token1);
        printf("%s %s\n",token,token1);
        es=factor();
        if (es>0) return es;
    }
    return es;
}

//<因子>::=(<算术表达式>)|<标识符>|<无符号整数>
//< factor >::=(<additive_expr>)| ID|NUM
int factor()
{
    int es=0;
    if (strcmp(token,"(")==0){
        fscanf(fin,"%d %s %s\n",&wrow,token,token1);
        printf("%s %s\n",token,token1);
        es=expression(); //表达式
        if (es>0) return es;
        if (strcmp(token,")"))  return 6; //缺少右括号
        fscanf(fin,"%d %s %s\n",&wrow,token,token1);
        printf("%s %s\n",token,token1);
    }
    else{
        if (strcmp(token,"ID")==0){
            fscanf(fin,"%d %s %s\n",&wrow,token,token1);
            printf("%s %s\n",token,token1);
            return es;
        }
        else if (strcmp(token,"NUM")==0){
            fscanf(fin,"%d %s %s\n",&wrow,token,token1);
            return es;
        }
        else{
            return 7; //缺少操作数
        }
    }
    return es;
}

int main()
{
    system("C:\\Users\\Administrator\\Desktop\\test.exe");
    strcpy(Scanin,"C:\\Users\\Administrator\\Desktop\\out1.txt");
    strcpy(Scanout,"C:\\Users\\Administrator\\Desktop\\out2.txt");
    TESTparse(); //调语义分析
    return 0;
}
View Code

 

三、语义分析

特点同上

技术分享
#include <stdio.h>
#include <ctype.h>
#include <conio.h>
#include <string.h>
#include <windows.h>

int TESTparse();
int program();
int compound_Stat();
int statement();
int expression_Stat();
int expression();
int bool_expr();
int additive_expr();
int term();
int factor();
int if_stat();
int while_stat();
int for_stat();
int write_stat();
int read_stat();
int do_while_stat();
int declaration_stat();
int declaration_list();
int statement_list();
int compound_stat();
int expression_stat();

#define MAXVARTABLEP 500 //定义符号表的容量
#define MAXFILENAME 100  //文件名最大长度
#define MAXLENGTH 40     //字符串最大长度

struct Table             //定义符号表结构
{
    char name[MAXLENGTH];
    int address;
}vartable[MAXVARTABLEP];
int vartablep=0,labelp=0,datap=0;

int wrow;                                      //错误行号
FILE *fin,*fout;                               //输入输出文件的指针
char token[MAXLENGTH],token1[MAXLENGTH];       //token保存单词符号,token1保存单词值
char Scanin[MAXFILENAME],Scanout[MAXFILENAME]; //输入输出文件名

int TESTparse()
{    
    int es=0;
    if ((fin=fopen(Scanin,"r"))==NULL){  
        printf("\n打开%s错误!\n",Scanout);
        es=10;
    }
    
    if ((fout=fopen(Scanout,"w"))==NULL){  
        printf("\n打开%s错误!\n",Scanout);
        es=10;
    }
    
    if (es==0) es=program();
    printf("=====语法分析结果!======\n");
    switch(es)
    {
    case 0: printf("语义分析成功!\n");break;
    case 10:printf("打开文件失败!\n");break;
    case 1: printf("ERROR(%d): \"%s\"前面缺少{\n",wrow,token1);break;
    case 2: printf("ERROR(%d): \"%s\"前面缺少}\n",wrow,token1);break;
    case 3: printf("ERROR(%d): \"%s\"前面缺少标识符\n",wrow,token1);break;
    case 4: printf("ERROR(%d): \"%s\"前面缺少分号\n",wrow,token1);break;
    case 5: printf("ERROR(%d): \"%s\"前面缺少(\n",wrow,token1);break;
    case 6: printf("ERROR(%d): \"%s\"前面缺少)\n",wrow,token1);break;
    case 7: printf("ERROR(%d): \"%s\"前面缺少操作数\n",wrow,token1);break;
    case 9: printf("ERROR(%d): \"%s\"前面缺少主程序\n",wrow,token1);break;
    case 11:printf("ERROR(%d): 主程序名错误!\n",wrow);break;
    case 12:printf("ERROR(%d): \"%s\"前面缺少while\n",wrow,token1);break;
    case 21:printf("ERROR(%d): 符号表溢出\n",wrow);break;
    case 22:printf("ERROR(%d): 变量\"%s\"重复定义\n",wrow,token1);break;
    case 23:printf("ERROR(%d): 变量\"%s\"未声明\n",wrow,token1);break;
    case 25:printf("ERROR(%d): \"%s\"已超出程序末尾\n",wrow,token1);break;
    case 26:printf("ERROR(%d): else没有匹配的if\n",wrow);
    }
    fclose(fin);
    fclose(fout);
    return es;
}

//插入符号表
int name_def(char *name)
{    
    if (vartablep>=MAXVARTABLEP) return 21; //符号表溢出
    for (int i=vartablep-1;i>=0;i--){ 
        if (strcmp(vartable[i].name,name)==0){    
            return 22; //变量重复定义
        }
    }
    strcpy(vartable[vartablep].name,name);
    vartable[vartablep++].address=datap++;
    return 0;
}

//查询符号表返回地址
int lookup(char *name,int *paddress)
{
    for (int i=0;i<vartablep;i++){
        if (strcmp(vartable[i].name,name)==0){
            *paddress=vartable[i].address;
            return 0;
        }
    }
    return 23; //变量未声明
}

//<程序>::={<声明序列><语句序列>}
//program::={<declaration_list><statement_list>}
int program()
{
    int es=0;
    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    es=declaration_list(); //声明语句
    if (es>0) return es;
    
    printf("             符号表\n"); //符号表输出
    printf("        名字      地址\n");
    for(int i=0;i<vartablep;i++)
        printf("%10s%10d\n",vartable[i].name,vartable[i].address);
    
    if (strcmp(token,"main")) return 9; //main区
    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    if (strcmp(token,"ID")) return 11; //程序名
    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    if (strcmp(token,"{")) return 1; //判断是否‘{‘
    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    es=statement_list(); //语句序列
    if (es>0) return es;
    if (strcmp(token,"}")) return 2; //判断是否‘}‘
    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    if (strcmp(token,"EOF")) return 25; //超出程序末尾
    fprintf(fout,"        STOP\n"); //产生停止指令
    return es;
}

//<声明序列>::=<声明序列><声明语句>|<声明语句>
//<declaration_list>::=<declaration_list><declaration_stat>|<declaration_stat>
int declaration_list()
{
    int es=0;
    while (strcmp(token,"int")==0){
        es=declaration_stat();
        if (es>0) return es;
    }
    return es;
}

//<声明语句>::=int<变量>;
//<declaration_stat>::=int ID;
//<declaration_stat>↓vartablep,datap,codep ->int ID↑n@name-def↓n,t;
int declaration_stat()
{
    int es=0;
    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    while (1){ //支持连续定义
        if (strcmp(token,"ID"))    return 3; //不是标识符
        es=name_def(token1); //插入到符号表
        if (es>0) return es;
        fscanf(fin,"%d %s %s\n",&wrow,token,token1);
        printf("%s %s\n",token,token1);
        if (strcmp(token,",")==0){
            fscanf(fin,"%d %s %s\n",&wrow,token,token1);
            printf("%s %s\n",token,token1);
        }
        else break;
    }
    if (strcmp(token,";") )    return 4; //缺少分号
    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    return es;
}

//<语句序列>::=<语句序列><语句>|<语句>
//<statement_list>::=<statement_list><statement>|<statement>
int statement_list()
{
    int es=0;
    while (strcmp(token,"}")){
        es=statement();
        if (es>0) return es;
        if (strcmp(token,"EOF")==0){
            return 2; //缺少}
        }
    }
    return es;
}

//<语句>::=<if语句>|<while语句>|<for语句>|<read语句>|<write语句>|<复合语句>|<表达式语句>
//<statement>::= <if_stat>|<while_stat>|<for_stat>|<compound_stat>|<expression_stat>
int statement()
{
    int es=0;
    if ((strcmp(token,"if")==0 || strcmp(token,"else")==0)) es=if_stat();//<IF语句>
    else if (strcmp(token,"while")==0) es=while_stat();//<while语句>
    else if (strcmp(token,"for")==0) es=for_stat();//<for语句>
    else if (strcmp(token,"do")==0) es=do_while_stat(); //do_while语句
    else if (strcmp(token,"read")==0) es=read_stat();//<read语句>
    else if (strcmp(token,"write")==0) es=write_stat();//<write语句>
    else if (strcmp(token,"{")==0) es=compound_stat();//<复合语句>
    else if ((strcmp(token,"ID")==0 || strcmp(token,"NUM")==0 || strcmp(token,"(")==0) || strcmp(token,";")==0) es=expression_stat();//<表达式语句>
    return es;
}

//<IF语句>::=if(<表达式>)<语句>[else<语句>]
//<IF_stat>::=if(<expr>)<statement>[else<statement>]
//if (<expression>)@BRF↑label1 <statement > @BR↑label2 @SETlabel↓label1 
//[ else < statement >] @SETlabel↓label2
//  其中动作符号的含义如下
//  @BRF↑label1 :输出 BRF label1, 
//  @BR↑label2:输出 BR label2, 
//  @SETlabel↓label1:设置标号label1 
//  @SETlabel↓label2:设置标号label2
int if_stat()
{
    if (strcmp(token,"else")==0) return 26; //else未匹配if
    int es=0,label1,label2;
    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    if (strcmp(token,"("))     return 5; //缺少左括号
    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    es=expression();
    if (es>0) return es;
    if (strcmp(token,")"))  return 6; //缺少右括号
    label1=labelp++; //用label1记住条件为假时要转向的标号
    fprintf(fout,"        BRF LABEL%d\n",label1);
    
    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    es=statement(); //语句
    if (es>0) return es;
    
    label2=labelp++; //用label2记住要转向的标号
    fprintf(fout,"        BR LABEL%d\n",label2);
    fprintf(fout,"LABEL%d:\n",label1); //设置label1记住的标号
    
    if (strcmp(token,"else")==0){ //else部分处理
        fscanf(fin,"%d %s %s\n",&wrow,token,token1);
        printf("%s %s\n",token,token1);
        es=statement(); 
        if (es>0) return es;
    }
    fprintf(fout,"LABEL%d:\n",label2); //设置label2记住的标号
    return es;
}

//<复合语句>::={<语句序列>} 
//<compound_stat>::={<statement_list>} 
int compound_stat()
{
    int es=0;
    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    es=statement_list(); //语句序列
    if (es>0) return es;
    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    return es;
}

// <do_whilie语句>::do{语句序列}while(表达式)
// <do_whilie_stat>::do{statment_list}while(expression)
int do_while_stat()
{
    int es=0,label1,label2;  
    label1=labelp++;
    fprintf(fout,"LABEL%d:\n",label1); //设置label1标号
    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    if (strcmp(token,"{")) return 1; //缺少左括号
    es=statement(); //语句
    if (es>0) return es;
    printf("%s %s\n",token,token1);
    if(strcmp(token,"while")) return 12; //缺少while
    
    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    if (strcmp(token,"("))  return 5; //缺少左括号
    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);

    es=expression(); //表达式
    if (es>0) return es;
    label2=labelp++;
    fprintf(fout,"        BRF LABEL%d\n",label2);
    fprintf(fout,"        BR LABEL%d\n",label1);
    
    if (strcmp(token,")"))  return 6; //缺少右括号
    if (es>0) return es;
    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    fprintf(fout,"LABEL%d:\n",label2); //设置label2标号
    return es;
}

//<while语句>::=while(<表达式>)<语句>
//<while_stat>::=while(<expr>)<statement >
//<while_stat>::=while @SET↑labellabel1(<expression>) @BRF↑label2 
//                <statement >@BR↓label1 @SETlabel↓label2
//动作解释如下:
//@SETlabel↑label1:设置标号label1
//@BRF↑label2 :输出 BRF label2,
//@BR↓label1:输出 BR label1,
//@SETlabel↓label2:设置标号label2
int while_stat()
{
    int es=0,label1,label2;  
    label1=labelp++;
    fprintf(fout,"LABEL%d:\n",label1); //设置label1标号
    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    if (strcmp(token,"("))  return 5; //缺少左括号
    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    es=expression();
    if (es>0) return es;
    if (strcmp(token,")"))  return 6; //缺少右括号

    label2=labelp++;
    fprintf(fout,"        BRF LABEL%d\n",label2);
    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    es=statement();
    if (es>0) return es;
    fprintf(fout,"        BR LABEL%d\n",label1);
    fprintf(fout,"LABEL%d:\n",label2); //设置label2标号
    return es;
}

//<for语句>::=for(<表达式>;<表达式>;<表达式>)<语句>
//<for_stat>::=for(<expr>,<expr>,<expr>)<statement>
//<for_stat>::=for (<expression>;
//@SETlabel↑label1< expression >@BRF↑label2@BR↑label3;
//@SETlabel↑label4 < expression >@BR↓label1) 
//@SETlabel↓label3 <语句 >@BR↓label4@SETlabel↓label2 
//动作解释:
//     @SETlabel↓label1:设置标号label1
//    @BRF↑label2 :输出 BRF label2,
//    @BR↑label3:输出 BR label3,
//    @SETlabel↓label4:设置标号label4
//    @BR↑label1:输出 BR label1,
//    @SETlabel↓label3:设置标号label3
//    @BR↑label4:输出 BR label4,
//    @SETlabel↓label2:设置标号label2 
int for_stat()
{
    int es=0,label1,label2,label3,label4; 
    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    if (strcmp(token,"("))  return 5; //缺少左括号
    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    es=expression();
    if (es>0) return es;
    if (strcmp(token,";"))     return 4; //缺少分号
    
    label1=labelp++;
    fprintf(fout,"LABEL%d:\n",label1); //设置label1标号
    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    es=expression();
    if (es>0) return es;
    label2=labelp++;
    fprintf(fout,"        BRF LABEL%d\n",label2);
    label3=labelp++;
    fprintf(fout,"        BR LABEL%d\n",label3);
    if (strcmp(token,";"))  return 4; //缺少分号
    
    label4=labelp++;
    fprintf(fout,"LABEL%d:\n",label4); //设置label4标号
    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    es=expression();
    if (es>0) return es;
    fprintf(fout,"        BR LABEL%d\n",label1);
    if (strcmp(token,")"))  return 6; //缺少右括号

    fprintf(fout,"LABEL%d:\n",label3); //设置label3标号
    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    es=statement();
    if (es>0) return es;
    fprintf(fout,"        BR LABEL%d\n",label4);
    fprintf(fout,"LABEL%d:\n",label2); //设置label2标号
    return es;
}

//<read_语句>::=read<变量>;
//<read_stat>::=read ID;
//<read_stat>::=read ID↑n LOOK↓n↑d @IN@STI↓d;
//动作解释:
//@LOOK↓n↑d:查符号表n,给出变量地址d; 没有,变量没定义
//@IN:输出IN
//@STI↓d:输出指令代码STI d
int read_stat()
{
    int es=0,address;
    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    if (strcmp(token,"ID"))  return 3; //缺少标识符

    es=lookup(token1,&address);
    if (es>0) return es;
    fprintf(fout,"        IN   \n");
    fprintf(fout,"        STO   %d\n",address);
    fprintf(fout,"        POP\n");
    
    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    if (strcmp(token,";"))  return 4; //缺少分号
    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    return es;
}

//<write_语句>::=write <表达式>;
//<write_stat>::=write <expression>;
//<write_STR>::write <STR>;
//动作解释:
//@ OUT:输出 OUT
int write_stat()
{
    int es=0;
    fscanf(fin,"%d %s ",&wrow,token);
    printf("%s ",token);
    if (strcmp(token,"STR")==0){ //输出字符串
        fgets(token1,1024,fin);
        printf("%s",token1);
        fprintf(fout,"        OUTS %s",token1); //由于字符串不参与运算,单独考虑,定义OUTS为输出字符串指令
        fscanf(fin,"%d %s %s\n",&wrow,token,token1);
        printf("%s %s\n",token,token1);
        if (strcmp(token,";"))  return 4; //缺少分号
        //fprintf(fout,"        OUT\n");
        fscanf(fin,"%d %s %s\n",&wrow,token,token1);
        printf("%s %s\n",token,token1);
        return es;
    }
    fscanf(fin,"%s",&token1);
    printf("%s\n",token1);
    es=expression();
    if (es>0) return es;
    if (strcmp(token,";"))  return 4; //缺少分号
    fprintf(fout,"        OUT\n");
    fscanf(fin,"%d %s %s\n",&wrow,token,token1);
    printf("%s %s\n",token,token1);
    return es;
}

//<表达式语句>::=<<表达式>;|;
//<expression_stat>::=<expression>;|;
int expression_stat()
{
    int es=0;
    if (strcmp(token,";")==0){
        fscanf(fin,"%d %s %s\n",&wrow,token,token1);
        printf("%s %s\n",token,token1);
        return es;
    }
    es=expression();
    if (es>0) return es;
    if (strcmp(token,";")==0){
        fscanf(fin,"%d %s %s\n",&wrow,token,token1);
        printf("%s %s\n",token,token1);
        return es;
    }
    else{
        return 4; //缺少分号
    }
}

//<表达式>::=<标识符>=<布尔表达式>|<布尔表达式>
//<expr>::=ID=<bool_expr>|<bool_expr>
//<expression>::=ID↑n@LOOK↓n↑d@ASSIGN=<bool_expr>@STO↓d |<bool_expr>
int expression()
{
    int es=0,fileadd;
    char token2[MAXLENGTH+2],token3[MAXLENGTH+2];
    if (strcmp(token,"ID")==0){
        fileadd=ftell(fin); //记住当前文件位置
        fscanf(fin,"%d %s %s\n",&wrow,token2,token3);
        printf("%s %s\n",token2,token3);

        if (strcmp(token2,"=")==0){ //‘=‘
            int address;
            es=lookup(token1,&address);
            if (es>0) return es;
            fscanf(fin,"%d %s %s\n",&wrow,token,token1);
            printf("%s %s\n",token,token1);
            es=bool_expr();
            if (es>0) return es;
            fprintf(fout,"        STO %d\n",address);
            fprintf(fout,"        POP\n");
        }
        else{ //"=="
            fseek(fin,fileadd,0); //若非‘=‘则文件指针回到‘=‘前的标识符
            es=bool_expr();
            if (es>0) return es;
        }
    }
    else{
        es=bool_expr();
    }
    return es;
}

//<布尔表达式>::=<算术表达式>|<算术表达式>(>|<|>=|<=|==|!=)<算术表达式>
//<bool_expr>::=<additive_expr>|< additive_expr >(>|<|>=|<=|==|!=)< additive_expr >
//<bool_expr>::=<additive_expr>
//|< additive_expr >><additive_expr>@GT
//|< additive_expr ><<additive_expr>@LES
//|< additive_expr >>=<additive_expr >@GE
//|< additive_expr ><=< additive_expr >@LE
//|< additive_expr >==< additive_expr >@EQ
//|< additive_expr >!=< additive_expr >@NOTEQ
int bool_expr()
{
    int es=0;
    es=additive_expr();
    if (es>0) return es;
    if (strcmp(token,">")==0 || strcmp(token,">=")==0 || strcmp(token,"<")==0 || 
        strcmp(token,"<=")==0 || strcmp(token,"==")==0 || strcmp(token,"!=")==0){
        char token2[MAXLENGTH+2];
        strcpy(token2,token); //保存运算符
        fscanf(fin,"%d %s %s\n",&wrow,token,token1);
        printf("%s %s\n",token,token1);
        es=additive_expr();
        if (es>0) return es;
        
        if (strcmp(token2,">")==0) fprintf(fout,"        GT\n");
        if (strcmp(token2,">=")==0) fprintf(fout,"        GE\n");
        if (strcmp(token2,"<")==0) fprintf(fout,"        LES\n");
        if (strcmp(token2,"<=")==0) fprintf(fout,"        LE\n");
        if (strcmp(token2,"==")==0) fprintf(fout,"        EQ\n");
        if (strcmp(token2,"!=")==0) fprintf(fout,"        NOTEQ\n");
    }
    return es;
}

//<算术表达式>::=<项>{(+|-)<项>}
//<additive_expr>::=<term>{(+|-)< term >} 
//< additive_expr>::=<term>{(+< term >@ADD |-<项>@SUB)}
int additive_expr()
{
    int es=0;
    es=term();
    if (es>0) return es;
    while (strcmp(token,"+")==0 || strcmp(token,"-")==0){
        char token2[MAXLENGTH+2];
        strcpy(token2,token);
        fscanf(fin,"%d %s %s\n",&wrow,token,token1);
        printf("%s %s\n",token,token1);
        es=term();
        if (es>0) return es;
        
        if (strcmp(token2,"+")==0) fprintf(fout,"        ADD\n");
        if (strcmp(token2,"-")==0) fprintf(fout,"        SUB\n");
    }
    return es;
}

//<项>::=<因子>{(*|/)<因子>}
//< term >::=<factor>{(*| /)< factor >} 
//< term >::=<factor>{(*< factor >@MULT | /< factor >@DIV)} 
int term()
{
    int es=0;
    es=factor();
    if (es>0) return es;
    while (strcmp(token,"*")==0 || strcmp(token,"/")==0  || strcmp(token,"%")==0){
        char token2[MAXLENGTH+2];
        strcpy(token2,token);
        fscanf(fin,"%d %s %s\n",&wrow,token,token1);
        printf("%s %s\n",token,token1);
        es=factor();
        if (es>0) return es;
        
        if (strcmp(token2,"*")==0) fprintf(fout,"        MULT\n");
        if (strcmp(token2,"/")==0) fprintf(fout,"        DIV\n");
        if (strcmp(token2,"%")==0) fprintf(fout,"        MOD\n");
    }
    return es;
}

//<因子>::=(<算术表达式>)|<标识符>|<无符号整数>
//< factor >::=(<additive_expr>)| ID|NUM
//< factor >::=(< expression >)| ID↑n@LOOK↓n↑d@LOAD↓d |NUM↑i@LOADI↓i
int factor()
{
    int es=0;
    if (strcmp(token,"(")==0){
        fscanf(fin,"%d %s %s\n",&wrow,token,token1);
        printf("%s %s\n",token,token1);
        es=expression(); //表达式
        if (es>0) return es;
        if (strcmp(token,")"))  return 6; //缺少右括号
        fscanf(fin,"%d %s %s\n",&wrow,token,token1);
        printf("%s %s\n",token,token1);
    }
    else{
        if (strcmp(token,"ID")==0){
            int address;
            es=lookup(token1,&address); //查符号表,获取地址
            if (es>0) return es; //变量没声明
            fprintf(fout,"        LOAD %d\n",address);
            fscanf(fin,"%d %s %s\n",&wrow,token,token1);
            printf("%s %s\n",token,token1);
            return es;
        }
        else if (strcmp(token,"NUM")==0){
            fprintf(fout,"        LOADI %s\n",token1);
            fscanf(fin,"%d %s %s\n",&wrow,token,token1);
            return es;
        }
        else{
            return 7; //缺少操作数
        }
    }
    return es;
}

int main()
{
    system("C:\\Users\\Administrator\\Desktop\\test.exe");
    strcpy(Scanin,"C:\\Users\\Administrator\\Desktop\\out1.txt");
    strcpy(Scanout,"C:\\Users\\Administrator\\Desktop\\out2.txt");
    TESTparse(); //调语义分析
    return 0;
}
View Code

 

四、模拟机

特点:

(1)支持字符串(可带空白字符)输出

(2)消除LABEL:中:与带:字符串的冲突

技术分享
#include <iostream>
#include <cstdio>
#include <cctype>
#include <cstdlib>
#include <cstring>
using namespace std;
#define INF 0x3f3f3f3f
#define MAXFILENAME 100
#define MAXCODENUM 1000
#define MAXCODELENGTH 100
#define MAXDATANUM 1000
#define MAXLABELNUM 100
#define MAXSTACK 1000

FILE *fin;                              //用于指向输入文件的指针
char Scanin[MAXFILENAME];               //用于接收输入的文件名
char code[MAXCODENUM][MAXCODELENGTH];   //代码存放数组
int data[MAXDATANUM];                   //data[i]表示i地址的数值
int label[MAXLABELNUM];                 //LABEL数组
int stack[MAXSTACK],stacktop;           //操作栈
char lno[10];
int codecnt;
int i,j,es;

int TESTmachine()
{
    es=0,i=0,j=0,stacktop=0;
    memset(data,-INF,sizeof(data));
    if ((fin=fopen(Scanin,"r"))==NULL){  
      printf("\n打开%s错误!\n",code);
      return 10;
    }

    codecnt=0;
    i=fscanf(fin,"%s",&code[codecnt]);
    while (!feof(fin)){ //读入
        i=strlen(code[codecnt])-1;
        strncpy(lno,code[codecnt],5);
        lno[5]=\0;
        if (strcmp(lno,"OUTS")==0){ //带空格字符串处理
            codecnt++;
            getc(fin); //跳过空格
            fgets(code[codecnt],1024,fin);
            i=strlen(code[codecnt])-1;
            code[codecnt][i]=\0;
        }
        else if (code[codecnt][i]==:){ //LABEL,已消除":"冲突
            i=i-5;
            strncpy(lno,&code[codecnt][5],i);
            lno[i]=\0;
            label[atoi(lno)]=codecnt; //用label数组记住每个标号的地址
            code[codecnt][0]=:;
            code[codecnt][1]=\0;
            strcat(code[codecnt],lno);
            j++;
        }
        codecnt++;
        i=fscanf(fin,"%s",&code[codecnt]);
    }
    fclose(fin);
    
    for (i=0;i<codecnt;i++){ //处理
        int l=strlen(code[i]);
        //printf("%d  %s  %d\n",i,code[i],l);
        if ((l>1) && (code[i][1]==A)){
            strncpy(lno,&code[i][5],l-5);
            lno[i]=\0;
            itoa(label[atoi(lno)],code[i],10);
        }
    }
    
    i=0;
    while (i<codecnt) //运行
    {
        if (strcmp(code[i],"LOAD")==0){ //LOAD D将D中的内容加载到操作数栈
            i++;
            stack[stacktop]=data[atoi(code[i])];
            stacktop++;
        }
        else if (strcmp(code[i],"LOADI")==0){ //LOADI a将常量a压入操作数栈
            i++;
            stack[stacktop]=atoi(code[i]);
            stacktop++;
        }
        else if (strcmp(code[i],"STO")==0){ //STO D将操作数栈栈顶单元内容存入D,且栈顶单元内容保持不变
            i++;
            data[atoi(code[i])]=stack[stacktop-1];
        }
        else if (strcmp(code[i],"STI")==0){ //STI D 将操作数栈栈顶单元内容存入D,且栈顶单元内容出栈
            i++;
            data[atoi(code[i])]=stack[stacktop-1];
            stacktop--;
        }
        else if(strcmp(code[i],"POP")==0){ //POP出栈
            stacktop--;
        }
        
        else if (strcmp(code[i],"ADD")==0){ //ADD将次栈顶单元与栈顶单元内容出栈并相加,和置于栈顶
            stack[stacktop-2]=stack[stacktop-2]+stack[stacktop-1];
            stacktop--;
        }
        else if (strcmp(code[i],"SUB")==0){ //SUB将次栈顶单元减去栈顶单元内容并出栈,差置于栈顶
            stack[stacktop-2]=stack[stacktop-2]-stack[stacktop-1];
            stacktop--;
        }
        else if (strcmp(code[i],"MULT")==0){ //MULT将次栈顶单元与栈顶单元内容出栈并相乘,积置于栈顶
            stack[stacktop-2]=stack[stacktop-2]*stack[stacktop-1];
            stacktop--;
        }
        else if (strcmp(code[i],"DIV")==0){ //DIV将次栈顶单元与栈顶单元内容出栈并相除,商置于栈顶
            stack[stacktop-2]=stack[stacktop-2]/stack[stacktop-1];
            stacktop--;
        }
        else if (strcmp(code[i],"MOD")==0){ //MOD将次栈顶单元模栈顶单元内容并出栈,余数置于栈顶
            stack[stacktop-2]=stack[stacktop-2]%stack[stacktop-1];
            stacktop--;
        }

        
        else if (strcmp(code[i],"BR")==0){ //BR lab无条件转移到lab
            i++;
            i=atoi(code[i]);            
        }
        else if (strcmp(code[i],"BRF")==0){ //BRF lab检查栈顶单元逻辑值,若为假则转移到lab
            i++;
            if (stack[stacktop-1]==0) i=atoi(code[i]);    
            stacktop--;
        }
        else if (strcmp(code[i],"EQ")==0){ //EQ将栈顶两单元做等于比较,并将结果真或假置于栈顶
            stack[stacktop-2]=stack[stacktop-2]==stack[stacktop-1];
            stacktop--;
        }
        else if (strcmp(code[i],"NOTEQ")==0){ //NOTEQ将栈顶两单元做不等于比较,并将结果真或假置于栈顶
            stack[stacktop-2]=stack[stacktop-2]!=stack[stacktop-1];
            stacktop--;
        }
        else if (strcmp(code[i],"GT")==0){ //GT次栈顶大于栈顶操作数,则栈顶置1,否则置0
            stack[stacktop-2]=stack[stacktop-2]>stack[stacktop-1];
            stacktop--;
        }
        else if (strcmp(code[i],"LES")==0){ //LES次栈顶小于栈顶操作数,则栈顶置1,否则置0
            stack[stacktop-2]=stack[stacktop-2]<stack[stacktop-1];
            stacktop--;
        }
        else if (strcmp(code[i],"GE")==0){ //GE次栈顶大于等于栈顶操作数,则栈顶置1,否则置0
            stack[stacktop-2]=stack[stacktop-2]>=stack[stacktop-1];
            stacktop--;
        }
        else if (strcmp(code[i],"LE")==0){ //LE 次栈顶小于等于栈顶操作数,则栈顶置1,否则置0
            stack[stacktop-2]=stack[stacktop-2]<=stack[stacktop-1];
            stacktop--;
        }
        else if (strcmp(code[i],"AND")==0){ //AND 将栈顶两单元做逻辑与运算,并将结果真或假置于栈顶
            stack[stacktop-2]=stack[stacktop-2] && stack[stacktop-1];
            stacktop--;
        }
        else if (strcmp(code[i],"OR")==0){ //OR将栈顶两单元做逻辑或运算,并将结果真或假置于栈顶
            stack[stacktop-2]=stack[stacktop-2]||stack[stacktop-1];
            stacktop--;
        }
        else if (strcmp(code[i],"NOT")==0){ //NOT将栈顶的逻辑值取反
            stack[stacktop-1]=!stack[stacktop-1];
        }

        else if (strcmp(code[i],"IN")==0){ //IN从标准输入设备(键盘)读入一个整型数据,并入栈
            scanf("%d",&stack[stacktop]);
            stacktop++;
        }
        else if (strcmp(code[i],"OUT")==0){ //OUT将栈顶单元内容出栈,并输出到标准输出设备上(显示器)
            printf("%d\n",stack[stacktop-1]);
            stacktop--;
        }
        else if (strcmp(code[i],"OUTS")==0){ //OUTS 字符串输出
            i++;
            printf("%s\n",code[i]);
        }
        
        else if (strcmp(code[i],"STOP")==0){ //STOP 停止执行
            break;
        }
        i++;
    }
    return es;
}
int main()
{
    //printf("请输入目标文件名(包括路径):\n");
    system("C:\\Users\\Administrator\\Desktop\\test4.exe");
    strcpy(Scanin,"C:\\Users\\Administrator\\Desktop\\out2.txt");
    //strcpy(Scanin,"TXT\\out2.txt");
    //scanf("%s",Scanin);

    TESTmachine();
    system("pause");
    return 0;
}
View Code

 

另外用QT写了一个简单界面,如图所示:

技术分享

技术分享

Test语言编译器V1.0

标签:

原文地址:http://www.cnblogs.com/hate13/p/4617327.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!