编译原理实验-词法分析

简介: 编译原理实验C语言实现

设计、编制并调试一个词法分析器---编译原理实验报告

image.png

image.png

image.png


源代码如下


#include <stdio.h>
#include "stdlib.h"
#include "string.h"

#define _KEY_WORD_END "waiting for your expanding" //关键字结束标志

typedef struct word{
   
   
    int typenum;
    char * word;
}WORD;

char  input[255]; //换入缓冲区
char  token[255] = ""; //单词缓冲区
int p_input; //换入缓冲区指针
int p_token; //单词缓冲区指针

char ch; //当前读入字符
char * rwtab[] = {
   
   "begin","if","then","while","do","end",_KEY_WORD_END};
WORD * scaner();


int main() {
   
   
    int over = 1;
    WORD * oneword;
    oneword->typenum = 0;
    oneword->word = NULL;

    printf("Enter Your words (end with #):");
    scanf("%[^#]s",input);
    p_input = 0;
    printf("Your words:\n%s\n",input);
    while (over < 1000 && over != -1){
   
   
        //分析源程序,直至碰到#
        oneword = scaner(); //获得一个新单词
        if(oneword -> typenum < 1000){
   
   
            printf("(%d,%s)",oneword -> typenum,oneword -> word);
        }

        over = oneword -> typenum;
    }

    printf("\n press # to exit:"); //按下#退出程序
    scanf("%[^#]s",input);
    return 0;
}


//从缓冲区读取一个字符到ch
char m_getch(){
   
   
    ch = input[p_input];
    p_input = p_input + 1;
    return ch;
}

//去掉空白符
void getbc(){
   
   
    while (ch == ' ' || ch == 10){
   
   
        ch = input[p_input];
        p_input = p_input + 1;
    }
}

//拼接单词
void concat(){
   
   
    token[p_token];
    p_token += 1;
    token[p_token] = '\0';
}

//判断是否为字母
int letter(){
   
   
    if(ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z'){
   
   
        return 1;
    } else
        return 0;
}

//判断是否为数字
int digit(){
   
   
    if(ch >= '0' && ch <= '9'){
   
   
        return 1;
    } else return 0;
}

int reserve(){
   
   
    int i = 0;
    while (strcmp(rwtab[i],_KEY_WORD_END)){
   
   
        if(!strcmp(rwtab[i],token)){
   
   
            return i+1;
        }
        i++;
    }
    return 10;
}

//回退一个字符
void retract(){
   
   
    p_input--;
}

//将输入的数字转换成二进制
char * dtb(int num){
   
   
    int binary[32],i = 0;
    while (num > 0){
   
   
        binary[i] = num % 2;
        num /= 2;
        i++;
    }
    for (int j = i - 1; j >= 0; --j) {
   
   
        printf("%d",binary[j]);
    }
}

//词法扫描程序
WORD * scaner(){
   
   
    WORD * myword;
    myword->typenum = 10;
    myword->word = "";
    p_token = 0;
    m_getch();
    getbc();
    if(letter()){
   
   
        while (letter() || digit()){
   
   
            concat();
            m_getch();
        }
        retract();
        myword -> typenum = reserve();
        myword -> word = token;
        return myword;
    } else if(digit()){
   
   
        while (digit()){
   
   
            concat();
            m_getch();
        }
        retract();
        myword -> typenum = 20;
        myword -> word = token;
        return myword;

    } else
        switch (ch) {
   
   
            case '=':
                m_getch();
                if(ch == '='){
   
   
                    myword -> typenum = 39;
                    myword -> word = '==';
                    return myword;
                }
                retract();
                myword -> typenum = 21;
                myword -> word = "=";
                return myword;
                break;

            case '+':
                myword -> typenum = 22;
                myword -> word = "+";
                return myword;
                break;

            case '-':
                myword -> typenum = 23;
                myword -> word = "-";
                return myword;
                break;

            case '*':
                myword -> typenum = 24;
                myword -> word = "*";
                return myword;
                break;

            case '/':
                myword -> typenum = 25;
                myword -> word = "/";
                return myword;
                break;

            case '(':
                myword -> typenum = 26;
                myword -> word = "(";
                return myword;
                break;

            case ')':
                myword -> typenum = 27;
                myword -> word = ")";
                return myword;
                break;

            case '[':
                myword -> typenum = 28;
                myword -> word = "[";
                return myword;
                break;

            case ']':
                myword -> typenum = 29;
                myword -> word = "]";
                return myword;
                break;

            case '{':
                myword -> typenum = 30;
                myword -> word = "{";
                return myword;
                break;

            case '}':
                myword -> typenum = 31;
                myword -> word = "}";
                return myword;
                break;

            case ',':
                myword -> typenum = 32;
                myword -> word = ",";
                return myword;
                break;

            case ':':
                myword -> typenum = 33;
                myword -> word = ":";
                return myword;
                break;

            case ';':
                myword -> typenum = 34;
                myword -> word = ";";
                return myword;
                break;

            case '>':
                m_getch();
                if(ch == '='){
   
   
                    myword -> typenum = 37;
                    myword -> word = ">=";
                    return myword;
                }
                retract();
                myword -> typenum = 35;
                myword -> word = ">";
                return myword;
                break;

            case '<':
                m_getch();
                if(ch == '='){
   
   
                    myword -> typenum = 38;
                    myword -> word = "<=";
                    return myword;
                }
                retract();
                myword -> typenum = 36;
                myword -> word = "<";
                return myword;
                break;

            case '!':
                m_getch();
                if(ch == '='){
   
   
                    myword -> typenum = 40;
                    myword -> word = "!=";
                    return myword;
                }
                retract();
                myword -> typenum = -1;
                myword -> word = "ERROR";
                return myword;
                break;

            case '\0':
                myword -> typenum = 1000;
                myword -> word = "OVER";
                return myword;
                break;

            default:
                myword -> typenum = -1;
                myword -> word = "ERROR";
                return myword;

        }
}
目录
相关文章
|
7月前
|
存储 自然语言处理 前端开发
编译原理 - 语义分析
编译原理 - 语义分析
100 1
|
7月前
|
自然语言处理 算法 前端开发
编译原理 - 词法分析
编译原理 - 词法分析
76 0
|
自然语言处理 前端开发 算法
编译原理 (二)词法分析、语法分析、语义分析以及中间代码生成器的基本概念
编译原理 (二)词法分析、语法分析、语义分析以及中间代码生成器的基本概念
819 0
|
自然语言处理
【编译原理】第二章,词法分析
【编译原理】第二章,词法分析
|
7月前
|
算法 编译器 C语言
编译原理 - 语法分析
编译原理 - 语法分析
98 0
|
7月前
|
存储 自然语言处理 编译器
【编译原理】词法分析:C/C++实现
【编译原理】词法分析:C/C++实现
338 1
|
7月前
|
自然语言处理
【编译原理】词法分析
【编译原理】词法分析
63 0
|
自然语言处理 IDE 开发工具
【编译原理】第三章语法分析
【编译原理】第三章语法分析
|
自然语言处理 网络安全 C语言
【编译原理】第二章,词法分析(更新)
【编译原理】第二章,词法分析
|
自然语言处理 C语言 C++
编译原理 实验二:词法分析器的手动实现(基于状态机的词法分析器)
编译原理 实验二:词法分析器的手动实现(基于状态机的词法分析器)
1102 0
编译原理 实验二:词法分析器的手动实现(基于状态机的词法分析器)