zoukankan      html  css  js  c++  java
  • 简单词法分析器的实现

    这是我们的一次编程作业,要求用C编写一个简单的词法分析器。要求如下:

    编制一个单词获取程序,从文件输入的源程序中,识别出各个具有独立意义的单词,即关键字、标识符、整数、小数、字符串、分隔符、运算符等七大类。并依次输出各个单词的内部编码及单词符号自身文本串(遇到错误时可显示“Error”,然后跳过错误部分继续显示)。

    注意:单词类型大小写不敏感(即不区分大小写)

    1、词法规则

    关键字: program、const、var、integer、decimal、string、procedure、begin、end 、if、then、else、while、do、call、read、write、not

    单词类别:1

    标识符: 字母或“_”打头的由字母、数字串或“_”组成的任意长度的符号串。

    单词类别:2

    整数:   数字串。

    单词类别:3

    小数:   数字串·数字串

    单词类别:4

    字符串: 由一对“”括起来的任意长度的符号串。注意:可以多行。

    单词类别:5

    分隔符: {、}、(、)、;、空格

    单词类别:6

    运算符: :=、=、<、<=、>、>=、+、-、*、/

    单词类别:7

    2、设计词法分析函数getToken( ),完成以下功能:

    1)getToken( )每调用一次就分析出一个单词;

    2)返回单词类别、单词自身文本串、单词在源文件中的行列号;

    3、编写测试程序,反复调用函数getToken ( ),输出单词信息。


    以下是代码实现:

    注意的事项:

      1,">="这一类操作符要进行判断。

      2,小数的识别。为了简便,我把小数当成字符串进行处理,后续可以加上一个字符串转数字的程序,或者直接直接识别成小数。

      3,输入的源程序如何判断结束,我使用的是"#"字符进行判断,应该可以通过使用EOF进行识别吧。

      4,超前搜索指针要回退。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    
    #define KW 1 //关键字
    #define ID 2 //标识符
    #define INT 3 //整数
    #define FLT 4 //小数
    #define STR 5 //字符串
    #define BRK 6 //分隔符
    #define OP 7 //操作符
    
    #define WordLen 100
    char prog[80],token[WordLen];
    char ch;
    int p,j,syn;
    int rowNum,lineNum;
    char *keyword[18] = {"program","const","var","integer","decimal","string","procedure",
                    "begin","end","if","then","else","while","do","call","read","write","not"};
    
    void getToken(){
        for(int i = 0;i < WordLen;i++)
            token[i] = NULL;
        ch = prog[p++];
        /*识别标识符或者变量名*/
        if(ch >= 'a'&&ch <= 'z'||ch == '_'){
            int i = 0;
            while((ch >= '0'&&ch <= '9')||(ch >= 'a'&&ch <= 'z')||ch == '_'){
                token[i++] = ch;
                ch = prog[p++];
            }
            token [i++] = '';
            p--;
            syn = ID;
            for(int n = 0;n < 18 ;n++){
                if(strcmp(token,keyword[n]) == 0){
                    syn = KW;
                    break;
                }
            }
        }
        /*识别实数*/
        else if(ch >= '0' && ch <= '9'){
            bool isDouble = false; //是否是小数
            j = 0;
            while(ch>='0'&&ch<='9'){
                token[j++] = ch;
                ch = prog[p++];
            }
            if(ch=='.'){
                isDouble = true;
                token[j++] = ch;
                ch = prog[p++];
                while((ch>='0' && ch<='9')){
                    token[j++] = ch;
                    ch = prog[p++];
                }
            }
            if(isDouble){
                syn = FLT;
            }
            if(!isDouble){
                syn = INT;
            }
            p--;
        }
        /*以下代码用于判断字符串*/
        else if(ch == '"'){
            j = 0;
            token[j++] = ch;
            while(prog[p] != '"'){
                token[j ++] = prog[p++];
            }
            token[j] = prog[p++];
            //p--;此处p不回退,因为上个while判断语句没有进行超前搜索。
            syn = STR;
        }
        /*以下代码用于判断运算符*/
        else switch(ch){//其他字符
            case'<':
                j = 0;
                token[j++] = ch;
                ch = prog[p++];
                if(ch == '='){
                    token[j++] = ch;
                    syn = OP;
                }
                else{
                    p--;
                    syn = OP;
                }
                break;
            case'>':
                j = 0;
                token[j++] = ch;
                ch = prog[p++];
                if(ch == '='){
                    token[j] = ch;
                    syn = OP;
                }
                else{
                    p--;
                    syn = OP;
                }
                break;
            case':':
                j = 0;
                token[j++] = ch;
                ch = prog[p++];
                if(ch == '='){
                    syn = OP;
                    token[j++] = ch;
                }
                else
                {
                    syn = -1;
                    p--;
                }
                break;
            case '=':syn = OP;token[0] = ch;break;
            case '+':syn = OP;token[0] = ch;break;
            case '*':syn = OP;token[0] = ch;break;
            case '/':syn = OP;token[0] = ch;break;
            case '{':syn = BRK;token[0] = ch;break;
            case '}':syn = BRK;token[0] = ch;break;
            case '(':syn = BRK;token[0] = ch;break;
            case ')':syn = BRK;token[0] = ch;break;
            case ';':syn = BRK;token[0] = ch;break;
            case ' ':syn = BRK;token[0] = ch;break;
            case '
    ':syn = -2;rowNum = 0;break;
            case '#':syn = 0;break;
            default :syn = -1;break;
        }
    }
    int main()
    {
        //freopen("D:\compiler.txt","r",stdin);
        p = 0;
        lineNum = 1;
        gets(prog);
        for(int m = 0;m < sizeof(prog);m++){
            if(prog[m] >= 'A'&&prog[m] <= 'Z'){
                prog[m] = prog[m] - 'A' + 'a';
            }
        }
        do {
            getToken();
            rowNum++;
            switch(syn)
            {
                case 1: cout<<lineNum<<" "<<rowNum<<" "<<"("<<syn<<","<<token<<")"<<endl;break;
                case 2: cout<<lineNum<<" "<<rowNum<<" "<<"("<<syn<<","<<token<<")"<<endl; break;
                case 5: cout<<lineNum<<" "<<rowNum<<" "<<"("<<syn<<","<<token<<")"<<endl; break;
                case 6: cout<<lineNum<<" "<<rowNum<<" "<<"("<<syn<<","<<token[0]<<")"<<endl; break;
                case 3: cout<<lineNum<<" "<<rowNum<<" "<<"("<<syn<<","<<token<<")"<<endl; break;
                case 4: cout<<lineNum<<" "<<rowNum<<" "<<"("<<syn<<","<<token<<")"<<endl; break;
                case -1: cout<<"Error !"<<endl; break;
                case -2: lineNum = lineNum++;break;
                case 0:break;
            }
        }while(syn != 0);
        return 0;
    }
    Donghua University
  • 相关阅读:
    泛微云桥e-Bridge 目录遍历,任意文件读取
    (CVE-2020-8209)XenMobile-控制台存在任意文件读取漏洞
    selenium 使用初
    将HTML文件转换为MD文件
    Python对word文档进行操作
    使用java安装jar包出错,提示不是有效的JDK java主目录
    Windows server 2012安装VM tools异常解决办法
    ifconfig 命令,改变主机名,改DNS hosts、关闭selinux firewalld netfilter 、防火墙iptables规则
    iostat iotop 查看硬盘的读写、 free 查看内存的命令 、netstat 命令查看网络、tcpdump 命令
    使用w uptime vmstat top sar nload 等命令查看系统负载
  • 原文地址:https://www.cnblogs.com/ohxiaobai/p/4394384.html
Copyright © 2011-2022 走看看