其他分享
首页 > 其他分享> > 编译原理实验一

编译原理实验一

作者:互联网

编译原理实验一

实验指导书源程序的改进版

程序一:

#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#define ID 7
#define INT 8
#define REAL 9
#define LT 10
#define LE 11
#define EQ 12
#define NE 13
#define GT 14
#define GE 15
#define IS 16
#define PL 17
#define MI 18
#define MU 19
#define DI 20

char TOKEN[20];
void report_error(char *s)
{
    printf("Having Error: %s", *s);
}
void out(int x, char *s)
{
    switch (x)
    {
    case 7:
    {
        printf("%s,%s\n", "ID", *s);
        break;
    }
    case 8:
    {
        printf("%s,%s\n", "INT", *s);
        break;
    }
    case 10:
    {
        printf("%s,%s\n", "LT", *s);
        break;
    }
    case 11:
    {
        printf("%s,%s\n", "LE", *s);
        break;
    }
    case 12:
    {
        printf("%s,%s\n", "EQ", *s);
        break;
    }
    case 13:
    {
        printf("%s,%s\n", "NE", *s);
        break;
    }
    case 14:
    {
        printf("%s,%s\n", "GT", *s);
        break;
    }
    case 15:
    {
        printf("%s,%s\n", "GE", *s);
        break;
    }
    case 16:
    {
        printf("%s,%s\n", "IS", *s);
        break;
    }
    case 17:
    {
        printf("%s,%s\n", "PL", *s);
        break;
    }
    case 18:
    {
        printf("%s,%s\n", "MI", *s);
        break;
    }
    case 19:
    {
        printf("%s,%s\n", "MU", *s);
        break;
    }
    case 20:
    {
        printf("%s,%s\n", "DI", *s);
        break;
    }
    default:
    {
        printf("%s,%s\n", KeyWordTable[x], *s);
        break;
    }
    }
}

/* 建立保留字表 */
#define MAX_KEY_NUMBER 20                         /*关键字的数量*/
#define KEY_WORD_END "waiting for your expanding" /*关键字结束标记*/
char *KeyWordTable[MAX_KEY_NUMBER] = {"begin", "end", "if", "then", "else", "switch", "case", KEY_WORD_END};
/* 查保留字表,判断是否为关键字 
不是关键字,返回0,是关键字,返回n+1, n为关键字数组中所找到的相同的关键字的索引位置*/
int lookup(char *token)
{
    int n = 0;
    while (strcmp(KeyWordTable[n], KEY_WORD_END)) /*如果比较到最后一位,也就是KEY_WORD_END,也就是已经确定都没有相同的,返回0*/
    {
        /*strcmp比较两串是否相同,若相同返回0*/
        /*相等:strcmp函数返回0,加上!后为:TRUE 进入if内部执行语句;
        不相等: strcmp返回其他正数或负数,这些返回值都等价于:TRUE ,加上!后,都为:FALSE 不进入if内部语句*/
        if (!strcmp(KeyWordTable[n], token))
        {
            return n + 1; /*根据单词分类码表I,设置正确的关键字类别码,并返回此类别码的值*/
            break;
        }
        n++;
    }
    return 0; /*单词不是关键字,而是标识符*/
}

void scanner_example(FILE *fp)
{
    char ch;
    int i = 0;
    int c = 0;
    ch = fgetc(fp); /*取出一个字符*/

    /*首字符为字母,字母数字混杂*/
    if (isalpha(ch)) /*是否是字母*/
    {
        TOKEN[0] = ch;
        ch = fgetc(fp); /*取出下一个字符*/
        i = 1;
        while (isalnum(ch)) /*是否是字母或者数字*/
        {
            TOKEN[i] = ch;
            i++;
            ch = fgetc(fp); /*取出一个字符*/
        }
        /*跳出循环之后,fp指针指向的字符,不再是数字或者字母*/
        TOKEN[i] = '\0';
        fseek(fp, -1, 1);  /*fp指针从当前位置往前挪一位*/
        c = lookup(TOKEN); /*判断是否是关键字,不是的话返回0*/
        if (c == 0)
            out(ID, TOKEN);
        else
            out(c - 1, " "); /*因为lookup函数返回值为n+1*/
    }
    /*首字符是数字,整型数字*/
    else if (isdigit(ch)) /*是否是数字*/
    {
        TOKEN[0] = ch;
        ch = fgetc(fp); /*取出第二个字符*/
        i = 1;
        while (isdigit(ch)) /*后面取出的字符都依然是数字*/
        {
            TOKEN[i] = ch;
            i++;
            ch = fgetc(fp);
        }
        /*跳出循环之后,fp指针指向的字符,不再是数字*/
            TOKEN[i] = '\0';
            fseek(fp, -1, 1); /*fp指针从当前位置往前挪一位*/
            out(INT, TOKEN);
    }
    else
    {
        switch (ch)
        {
        case '<':
        {
            ch = fgetc(fp);
            if (ch == '=')
                out(LE, " ");
            else if (ch == '>')
                out(NE, " ");
            else
            {                     /*下一位不是=或者> :当做只有< */
                fseek(fp, -1, 1); /*fp指针从当前位置往前挪一位*/
                out(LT, " ");
            }
            break;
        }
        case '=':
        {
            out(EQ, " ");
            break;
        }
        case '>':
        {
            ch = fgetc(fp);
            if (ch == '=')
                out(GE, " ");
            else
            {                     /*下一位不是= :当做只有> */
                fseek(fp, -1, 1); /*fp指针从当前位置往前挪一位*/
                out(GT, " ");
            }
            break;
        }
        case ':':
        {
            ch = fgetc(fp);
            if (ch == '=')
            {
                out(IS, " ");
            }
            else
            { /*冒号后面跟着的不是等号的话*/
                report_error(':');
                fseek(fp, -1, 1);
            }
        }
        case '+':
        {
            out(PL, " ");
        }
        case '-':
        {
            out(MI, " ");
        }
        case '*':
        {
            out(MU, " ");
        }
        case '/':
        {
            out(DI, " ");
        }
        default:
        {
            report_error(ch);
            break;
        }
        }
    }

    return;
}

程序二

#include <stdio.h>
#include <ctype.h>
#include <math.h>
#include<stdlib.h>

#define DIGIT 1
#define POINT 2
#define OTHER 3
#define POWER 4
#define PLUS  5
#define MINUS 6
#define UCON  7 
/*Suppose the class number of unsigned constant is 7
假设无符号常量的类数为7*/
#define ClassOther 200
#define EndState -1
int w, n, p, e, d;
int Class; 
/*Used to indicate class of the word
用来表示单词的类别*/
int ICON;
float FCON;
static int CurrentState; 
/*Used to present current state, the initial value:0
用于表示当前状态,初始值:0*/

int GetChar(void);
int EXCUTE(int, int);
int HandleOtherWord(void)
{
    return ClassOther;
}
int HandleError(void)
{
    printf("Error!\n");
    return 0;
}

int GetChar(void)
{
    int c;
    c = getchar();
    if (isdigit(c))
    {
        d = c -'0';
        return DIGIT;
    }
    if (c =='.')
        return POINT;
    if (c =='E'|| c =='e')
        return POWER;
    if (c =='+')
        return PLUS;
    if (c =='-')
        return MINUS;
    return OTHER;
}
int EXCUTE(int state, int symbol)
{
    switch (state)
    {
    case 0:
        switch (symbol)
        {
        case DIGIT:
            n = 0;
            p = 0;
            e = 1;
            w = d;
            CurrentState = 1;
            Class = UCON;
            break;
        case POINT:
            w = 0;
            n = 0;
            p = 0;
            e = 1;
            CurrentState = 3;
            Class = UCON;
            break;
        default:
            HandleOtherWord();
            Class = ClassOther;
            CurrentState = EndState;
        }
        break;
    case 1:
        switch (symbol)
        {
        case DIGIT:
            w = w * 10 + d;
            break; //CurrentState=1
        case POINT:
            CurrentState = 2;
            break;
        case POWER:
            CurrentState = 4;
            break;
        default:
            ICON = w;
            CurrentState = EndState;
        }
        break;
    case 2:
        switch (symbol)
        {
        case DIGIT:
            n++;
            w = w * 10 + d;
            break;
        case POWER:
            CurrentState = 4;
            break;
        default:
            FCON = w * pow(10, e * p - n);
            CurrentState = EndState;
        }
        break;
    case 3:
        switch (symbol)
        {
        case DIGIT:
            n++;
            w = w * 10 + d;
            CurrentState = 2;
            break;
        default:
            HandleError();
            CurrentState = EndState;
        }
        break;
    case 4:
        switch (symbol)
        {
        case DIGIT:
            p = p * 10 + d;
            CurrentState = 6;
            break;
        case MINUS:
            e = -1;
            CurrentState = 5;
            break;
        case PLUS:
            CurrentState = 5;
            break;
        default:
            HandleError();
            CurrentState = EndState;
        }
        break;
    case 5:
        switch (symbol)
        {
        case DIGIT:
            p = p * 10 + d;
            CurrentState = 6;
            break;
        default:
            HandleError();
            CurrentState = EndState;
        }
        break;
    case 6:
        switch (symbol)
        {
        case DIGIT:
             p = p * 10 + d;
            break;
        default:
            FCON = w * pow(10, e * p - n);
            CurrentState = EndState;
        }
        break;
    }
    return CurrentState;
}
int LEX(void)
{
    int ch;
    CurrentState = 0;
    while (CurrentState != EndState)
    {
        ch = GetChar();
        EXCUTE(CurrentState, ch);
    }
    //return Class;
    printf("w: %d  n: %d  p: %d  e: %d  d: %d", w, n, p, e, d);
    printf("\n ICON: %.3f, FCON: %.3f CLASS: %d", ICON, FCON, Class);
}
int main(){
    LEX();
    system("pause");
}

但是程序二是建立在手动输入上的,需要将程序一二做一个合体改造

程序:

waiting

标签:case,ch,int,break,编译,实验,原理,CurrentState,define
来源: https://blog.csdn.net/caoxiaobao1207/article/details/121042574