b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

编译原理(1)词法分析程序(C++实现)

电脑杂谈  发布时间:2019-07-28 23:11:22  来源:网络整理

c代码实现文件无限自我复制_c 代码实现打开文件_c++实现发邮件到qq信箱 病毒代码

这是关于编译原理的第一篇文章。

本科阶段的教学与实际操作存在一些脱节的现象。比如词法编辑器你可以完全在不知道什么nfadfa啊之类东西情况下强行摸索出来,而书上和上课讲的却是各种状态转换之类的东西。还要去背因为考试得考。这样堪称上课与书面考试是一套东西,写代码的时候可能是另一套东西。(可能老师认为代码这种东西学生自学就好)。(当然造成这种结论很有可能是本人知识有限的缘故)

介绍:构造一个自定义的小型语言的词法分析程序,程序要求能从文件输入的源程序中对输入的字符串流进行词法分析。

单词种类与词法规则

1标识符:首字符为字母或下划线,其后由字母、数字或下划线组成;

注:标识符长度不能超过20个字符。

2无符号整数:由十进制数字组成的一个序列。首位数字不能为0;

注:无符号整数不带正负号。

c 代码实现打开文件_c代码实现文件无限自我复制_c++实现发邮件到qq信箱 病毒代码

③保留字:procedure、def、if、else、while、call、begin、end、and、or

注:保留字不区分大小写。

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

⑤双目运算符:<=、 >=、 <>、 ==

⑥ 界符: ( ) ,;

注释:单行注释和多行注释(注释语法同C语言)。

注:这个词法的规则将会继续在之后的语法等环节沿用。

环境:普通win10,c++语言 直接任意IDE编译运行即可

c++实现发邮件到qq信箱 病毒代码_c代码实现文件无限自我复制_c 代码实现打开文件

关于本程序的说明:解析相同目录下的code.txt文件c++实现发邮件到qq信箱 病毒代码,被分析的代码写在那个文本文件里就好。

#include<iostream>
#include<fstream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
using namespace std;
int aa;// fseek的时候用来接着的
string  word="";
string  reserved_word[11];//保留
char buffer;//每次读进来的一个字符
int num=0;//每个单词中当前字符的位置
int line=1; //行数
int row=1; //列数,就是每行的第几个
bool flag; //文件是否结束了
int flag2;//单词的类型
//设置保留字
void set_reserve()
{
    reserved_word[1]="procedure";
    reserved_word[2]="def";
    reserved_word[3]="if";
    reserved_word[4]="else";
    reserved_word[5]="while";
    reserved_word[6]="call";
    reserved_word[7]="begin";
    reserved_word[8]="end";
    reserved_word[9]="and";
    reserved_word[10]="or";
}
//看这个字是不是字母
bool judge_word(char x)
{
    if(x>='a' && x<='z' || x>='A' && x<='Z' ){
        return true;
    }
    else return false;
}
//看这个字是不是数字
bool judge_number(char x)
{
    if(x>='0' && x<='9'){
        return true;
    }
    else return false;
}
//看这个字符是不是界符
bool judge_jiefu(char x)
{
    if(x=='('||x==')'||x==','||x==';'){
        return true;
    }
    else return false;
}
//加减乘
bool judge_yunsuanfu1(char x)
{
    if(x=='+'||x=='-'||x=='*')
    {
        return true;
    }
    else return false;
}
//等于 赋值,大于小于 大于等于,小于等于,大于小于
bool judge_yunsuannfu2(char x)
{
    if(x=='='|| x=='>'||x=='<'){
        return true;
    }
    else return false;
}
//这个最大的函数的总体作用是从文件里读一个单词
int scan(FILE *fp)
{
    buffer=fgetc(fp);
    if(feof(fp)){
        flag=0;return 0;
    }
    //cout<<buffer;
    else if(buffer==' ')
    {
        row++;
        return 0;
    }
    else if(buffer=='\n')
    {
        line++;
        row=1;
        return 0;
    }
    //如果是字母开头或'_' 看关键字还是普通单词
    else if(judge_word(buffer) || buffer=='_')
    {
        word+=buffer;row++;
        while((buffer=fgetc(fp)) && (judge_word(buffer) || judge_number(buffer) || buffer=='_'))
        {
            word+=buffer;row++;
        }
        if(feof(fp)){
                flag=0;return 1;
        }
         //这个函数的意义是 因为保留字不区分大小写 要把大写字母全变成小写再比较
        string temp=word;
        for(int j=0;j<temp.length();j++)
        {
            if(temp[j]>='A' && temp[j]<='Z')
            {
                temp[j]+=32;
            }
        }
        for(int i=1;i<=10;i++){
            if(temp==reserved_word[i]){
                aa=fseek(fp,-1,SEEK_CUR);
                return 3;
            }
        }
        aa=fseek(fp,-1,SEEK_CUR);
        return 1;
    }
    //开始是加减乘 一定是类型4
    else if(judge_yunsuanfu1(buffer))
    {
        word+=buffer;row++;
        return 4;
    }
    //开始是数字就一定是数字
    else if(judge_number(buffer))
    {
        word+=buffer;row++;
        while((buffer=fgetc(fp)) && judge_number(buffer))
        {
            word+=buffer;row++;
        }
        if(feof(fp)){
                flag=0;return 2;
        }
        aa=fseek(fp,-1,SEEK_CUR);
        return 2;
    }
    //检验界符
    else if(judge_jiefu(buffer))
    {
        word+=buffer;row++;
        return 6;
    }
    //检验 <=、  >=、  <>、  == =、 <、>
    else if(judge_yunsuannfu2(buffer))
    {
        row++;
        word+=buffer;
        if(buffer=='<')   //为了检验题目中的<> <=
        {
            buffer=fgetc(fp);
            if(buffer=='>' || buffer=='=')
            {
                word+=buffer;
                row++;
                return 5;
            }
        }
        //检验  >= ==
        else{
            buffer=fgetc(fp);
            if(buffer=='=')
            {
                word+=buffer;
                row++;
                return 5;
            }
        }
        if(feof(fp)){
                flag=0;
        }
        aa=fseek(fp,-1,SEEK_CUR);
        return 4;
    }
    //首字符是/ 有可能是除号 也有可能是注释
    else if(buffer=='/')
    {
        row++;word+=buffer;
        buffer=fgetc(fp);
        //这种情况是除号
        if(buffer!='*' && buffer !='/')
        {
            aa=fseek(fp,-1,SEEK_CUR);
            return 4;
        }
        // 这一行剩下的全被注释了
        if(buffer=='/')
        {
            word.clear();
            while((buffer=fgetc(fp)) && buffer!='\n' &&!feof(fp))
            {
                //真的什么也没有做
            }
            if(feof(fp)){
                flag=0;return 0;
            }
            else{
               aa=fseek(fp,-1,SEEK_CUR);
            }
            line++;row=1;
            return 0;
        }
        if(buffer=='*')
        {
            bool flag5=1;
            while(flag5)
            {
                word.clear();
                buffer=fgetc(fp);
                row++;
                if(buffer=='\n'){line++;row=1;}
                if(buffer!='*')continue;
                else {
                    buffer=fgetc(fp);
                    row++;if(buffer=='\n'){line++;row=1;}
                    if(buffer=='/'){
                        flag5=0;
                    }
                    else continue;
                }
                if(feof(fp)){flag=0;return 0;}
            }
        }
    }
    else {
        word+=buffer;
        row++;
        return -1;
    }
}
int main()
{
    set_reserve();//设置保留字
    cout<<"introduction"<<endl;
    cout<<"open "<<"code.txt"<<endl;
    cout<<"press any key"<<endl;
    system("pause");
    flag=1;
    //ifstream a("需要解析的源代码.txt");
    FILE *fp;
    if(!(fp=fopen("code.txt","r")))
    {
        cout<<"not found the file or other error "<<endl;
        flag=0;
    }
    while(flag==1)
    {
        //flag2 返回的类型
        flag2=scan(fp);//反复调用函数提取单词
        if(flag2==1)
        {
            cout<<"type:1 identifier      "<<"line "<<line<<" row "<<row-word.length()<<"  "<<word<<endl;
            if(word.length()>20)
            cout<<"ERROR Identifier length cannot exceed 20 characters"<<endl;
            word.clear();
        }
        else if(flag2==3)
        {
            cout<<"type:3 reserved word   "<<"line "<<line<<" row "<<row-word.length()<<"  "<<word<<endl;
            word.clear();
        }
        else if(flag2==4)
        {
            cout<<"type:4 unary_operator  "<<"line "<<line<<" row "<<row-1<<"  "<<word<<endl;
            word.clear();
        }
        else if(flag2==2)
        {
            cout<<"type:2 positive number "<<"line "<<line<<" row "<<row-word.length()<<"  "<<word<<endl;
            if(word[0]=='0')
            cout<<"ERROR: The first digit cannot be 0!"<<endl;
            word.clear();
        }
        else if(flag2==6)
        {
            cout<<"type:6 Separator       "<<"line "<<line<<" row "<<row-1<<"  "<<word<<endl;
            word.clear();
        }
        else if(flag2==5)
        {
            cout<<"type:6 double_operator "<<"line "<<line<<" row "<<row-2<<"  "<<word<<endl;
            word.clear();
        }
        //非法字符
        else if(flag2==-1)
        {
           cout<<"Illegal character      "<<"line "<<line<<" row "<<row-1<<"  "<<word<<endl;
           word.clear();
        }
    }
        int a=fclose(fp);
        cout<<"press e to close"<<endl;
        char end;
        while(cin>>end && end!='e'){
            cout<<"只有e可以关闭"<<endl;
        }
    return 0;
}


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-116544-1.html

相关阅读
    发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

    • 李技高
      李技高

      连内容都必看就一喷到底

    每日福利
    热点图片
    拼命载入中...