zoukankan      html  css  js  c++  java
  • 编译原理,例:词法分析器

    编译原理课作业要求自己写一个词法分析器,我尝试写了一下。
    词法分析:计算机科学中将字符序列转换为单词(Token)序列的过程。进行词法分析的程序或者函数叫作词法分析器(Lexical analyzer),也叫扫描器(Scanner)。词法分析器一般以函数的形式存在,供语法分析器调用。 完成词法分析任务的程序称为词法分析程序或词法分析器或扫描器。完成词法分析任务的程序称为词法分析程序或词法分析器或扫描器。从左至右地对源程序进行扫描,按照语言的词法规则识别各类单词,并产生相应单词的属性字。
     
    词法分析是编译器对源代码进行编译处理的第一步。编写指定程序语言的词法分析器需要构造相应的有限自动机,然后根据其编写。
    目标:对下面的一段程序进行语法分析,输出分词。
    var n, f;
    begin
         n := 0;
         f := 1;
         while n # 10 do
         begin
              n := n + 1;
              f := f * n;
         end;
         call print;
    end.

    有限自动机在纸上手画的,这个语言的词法比较简单,算符界符表,保留字表比较少,我直接写到代码里了(*^▽^*)

    #include<iostream>
    #include <fstream>
    #include <cassert>
    
    using namespace std;
    
    bool IsDigit(char ch);
    bool IsLetter(char ch);
    int Reserve(string s);
    
    int main(){
        ifstream infile;    //文件输入流
        string file;    //文件路径
        int code;    //
        char ch;    //
        string strToken ;    //字符串
        cout<<"源程序路径:"<<endl;
        cin>>file;
    
        infile.open(file.data());    //将文件流对象与文件连接起来
        assert(infile.is_open());   //若失败,则输出错误消息,并终止程序运行
    
        infile >> noskipws    ;//noskipws:no skip whitespace 不跳过空格回车
    
        infile>>ch;
    
        while(!infile.eof()){
            strToken = "";
            while(ch==' '||ch=='
    '||ch=='
    '){
                if(infile.eof())    break;
                infile>>ch;//若是空白字符跳过
            }
            if(IsLetter(ch))//进入字母状态
            {
                while((IsLetter(ch)||IsDigit(ch)))
                {
                    strToken.append(1,ch);
                    infile>>ch;
                }
                code = Reserve(strToken);//查询保留字
                if(code==0) //不是保留字
                {
                    cout<<"< "<<strToken<<" , 标识符 >"<<endl;
                }
                else
                {
                    cout<<"< "<<strToken<<" , 保留字 >"<<endl;
                }
                continue;
            }
            else if(IsDigit(ch))//进入数字状态
            {
                while(IsDigit(ch)){
                    strToken.append(1,ch);
                    infile>>ch;
                }
                cout<<"< "<<strToken<<" , 常量 >"<<endl;
                continue;
            }
            else
            if(ch == '+') cout<<"< + , 算符 >"<<endl;
            else if(ch == '-') cout<<"< - , 算符 >"<<endl;
            else if(ch == '*') cout<<"< * , 算符 >"<<endl;
            else if(ch == '/') cout<<"< / , 算符 >"<<endl;
            else if(ch == '<') cout<<"< < , 算符 >"<<endl;
            else if(ch == '>') cout<<"< > , 算符 >"<<endl;
            else if(ch == ':')
            {
                infile>>ch;
                if(ch == '=')
                    cout<<"< := , 算符 >"<<endl;
                else
                    cout<<"Error :"<<ch<<endl;
            }
            else if(ch == 0x23) cout<<"<# ; , 界符 >"<<endl;
            else if(ch == 0x28) cout<<"< ( , 界符 >"<<endl;
            else if(ch == 0x29) cout<<"< ) , 界符 >"<<endl;
            else if(ch == 0x2c) cout<<"< , , 界符 >"<<endl;
            else if(ch == 0x2e) cout<<"< . , 界符 >"<<endl;
            else if(ch == 0x3b) cout<<"< ; , 界符 >"<<endl;
    
            else if(ch==' '||ch=='
    '||ch=='
    ')    continue;
            else cout<<"Error :"<<ch<<endl;
    
            infile>>ch;
    
            if(infile.eof())    break;
        }
    
        infile.close();//关闭文件输入流
        return 0;
    }
    
    bool IsDigit(char ch)
    {
        if(ch>='0'&&ch<='9') return true;
        else return false;
    }
    bool IsLetter(char ch)
    {
        if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))    return true;
        else return false;
    }
    int Reserve(string s)
    {
            if(s == "begin")    return 1;
            else if(s == "call")    return 2;
            else if(s == "const")    return 3;
            else if(s == "do")        return 4;
            else if(s == "end")        return 5;
            else if(s == "if")        return 6;
            else if(s == "odd")        return 7;
            else if(s == "procedure")    return 8;
            else if(s == "then")    return 9;
            else if(s == "var")        return 10;
            else if(s == "while")    return 11;
            else    return 0;
    }

    最后的输出:



     
  • 相关阅读:
    flex布局
    cookie设置、获取、删除
    使用Object对象的toString()方法自定义判断数据类型方法
    git使用汇总
    闭包和面向对象
    闭包
    java8之一文彻底弄懂lambda表达式
    正确理解MESI协议
    二叉树中的节点删除-----按照最底层最右边的节点收缩
    按层次插入二叉树
  • 原文地址:https://www.cnblogs.com/mydrizzle/p/12565176.html
Copyright © 2011-2022 走看看