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
  • 相关阅读:
    学到的一种编程风格
    防止忘记初始化NSMutableArray的方法
    == 和 isEqualToString的区别之备忘
    IOS开发中--点击imageView上的Button没有任何反应
    [__NSCFString absoluteURL]错误的解决方案
    二叉树镜像
    判断树的子结构
    算法练习-贪心问题
    重建二叉树:
    IDEA搭建web项目出现中文乱码问题
  • 原文地址:https://www.cnblogs.com/ohxiaobai/p/4394384.html
Copyright © 2011-2022 走看看