zoukankan      html  css  js  c++  java
  • 实验一:词法分析设计

    1.[实验目的]:

        1.了解词法分析的主要任务。
        2. 熟悉编译程序的编制。
      [实验内容]:根据某文法,构造一个基本词法分析程序。找出该语言的关键字、标识符、整数以及其他一些特殊符号,给出单词表(内容包括单词种类和值),构造符号表(内容包括name、kind、value和address等)。

    2.C 语言文法

    G[<程序>]:

    <程序>→main(){<声明部分><语句部分>}

    <声明部分>→<声明部分><常量声明部分>| <声明部分><变量声明部分>|<空>

    <常量声明部分>→const<常量定义>{,<常量定义>};

    <常量定义>→<类型> <标识符>=<无符号整数>;

    <无符号整数>→<数字>{<数字>}

    <变量声明部分>→<类型><标识符>{,<标识符>};

    <类型>→int|float|double|long|long long|char|bool

    <标识符>→<字母>{<字母>|<数字>}

    <语句部分>→<条件语句>|<while循环语句>|<for循环语句>|输入语句|输出语句|复合语句|<赋值语句>

    <条件语句>→if (<表达式>) <语句>;|if(<表达式>) else <语句>;

    <while循环语句>→while(<表达式>){<语句>}

    <for循环语句>→for(<表达式>;<表达式>;<表达式>){<语句>}

    <复合语句>→{<语句部分>}

    <赋值语句>→<表达式>

    <表达式>→<标识符>=<算数表达式>|<布尔表达式>

    <布尔表达式>→<算数表达式>|<算数表达式><关系运算符><算术表达式>

    <关系运算符>→<|>|==|!=|>=|<=

    <算数表达式>→<算数表达式>+<项>|<算数表达式>-<项>|<项>

    <项>→<项>*<因子>|<项>/<因子>|<因子>

    <因子>→<标识符>|<无符号整数>|(<算数表达式>)|true|false

     <字母>→a|b|…|z|A|B|…|Z

     <数字>→0|1|2|3|4|5|6|7|8|9

    3.单词分类情况表

    4.状态转换图

    5.程序设计

     词法分析程序

      1 #include <cstdio>
      2 #include <stdio.h>
      3 #include <cctype>
      4 #include <cstring>
      5 #include <iostream>
      6 #include <map>
      7 using namespace std;
      8 const string keyWord[20]= {"main","const","int","float","double","long","long long","char","while","for","if","else","false","true"};
      9 const string relSign[10]= {">","<",">=","<=","!=","==","="};
     10 
     11 struct signTable//符号表
     12 {
     13     string name;
     14     int value;
     15     int kind;
     16     int address;
     17 }record[520];
     18 map<string,bool>mpk;
     19 map<string,bool>mpr;
     20 int cnt = 0,num = 0;
     21 const char *p;
     22 void init()//建立关键字表
     23 {
     24     for (int i = 0; i < 14; i++)
     25         mpk[keyWord[i]] = true;
     26     for (int i = 0; i < 7; i++)
     27         mpr[relSign[i]] = true;
     28     cnt = 0,num = 0;
     29 }
     30 void alpha()//识别标识符
     31 {
     32     char save[250];
     33     int i = 0;
     34     string s ;
     35     while(isalnum(*p))
     36     {
     37         save[i++]=*p;
     38         p++;
     39     }
     40     save[i] = '';
     41     s = save;
     42     p--;
     43     if(mpk[s])//判断是否存在于关键字表中
     44         cout<<++cnt<<" keyword "<<s<<endl;
     45     else
     46         {
     47             record[num++].name = s;
     48             cout<<++cnt<<" captionsign "<<s<<endl;
     49         }
     50 }
     51 void digit()//识别数字
     52 {
     53     int i = 0;
     54     char save[250];
     55     string s;
     56     while(isdigit(*p))
     57     {
     58         save[i++] = *p;
     59         p++;
     60     }
     61     save[i] = '';
     62     s = save;
     63     p--;
     64     cout<<++cnt<<" digit "<<s<<endl;
     65 }
     66 void isRelSign()//识别关系运算符
     67 {
     68     char save[10];
     69     string s;
     70     int i = 0;
     71     while(i <= 1)
     72     {
     73         save[i++]=*p;
     74         p++;
     75     }
     76     p--;
     77     save[i] = '';
     78     s = save;
     79     if(mpr[s])//判断是否存在于关系运算符表中
     80         cout<<++cnt<<" relationsign "<<s<<endl;
     81     else
     82         {
     83             p--;
     84             if(*p=='!')
     85             cout<<++cnt<<" error "<<*p<<endl;
     86             else
     87             cout<<++cnt<<" relationsign "<<*p<<endl;
     88         }
     89 }
     90 int main()
     91 {
     92     string name,str,s,s1;
     93     char ss[1020],filename[20];
     94     cout<<"please input your program's filename:"<<endl;
     95     init();
     96     cin>>name;
     97     name+=".txt";//添加扩展名
     98     int len = name.size();
     99     name.copy(filename,len,0);
    100     filename[len]='';
    101     freopen(filename,"r",stdin);//读文件
    102     while(gets(ss))
    103     {
    104         s1 = ss;
    105         cout<<s1<<endl;//输出源程序
    106         str+=s1;
    107     }
    108     p = str.data();
    109     while(*p!='')
    110     {
    111         while(*p==' '||*p=='
    '||*p=='	') p++;
    112         if(isalpha(*p)) alpha();//判断标识符
    113         else if(isdigit(*p)) digit();//判断数字
    114         else if (*p=='('||*p==')'||*p=='{'||*p=='}'||*p==','||*p==';')//判断界符
    115             cout<<++cnt<<" boundarysign "<<*p<<endl;
    116         else if (*p=='+'||*p=='-'||*p=='*'||*p=='/')//判断算数运算符
    117             cout<<++cnt<<" arithmaticsign "<<*p<<endl;
    118         else if(*p=='>'||*p=='<'||*p=='='||*p=='!')//判断关系运算符
    119             isRelSign();
    120         else
    121             cout<<++cnt<<" error "<<p<<endl;//出错处理
    122         p++;
    123     }
    124     fclose(stdin);//关闭文件
    125     return 0;
    126 }
    View Code

     

     (1) 用map容器存储关键字和关系运算符,map容器内部是用红黑树实现的,查找效率为O(ln(N)),查找效率较高。

     (2) 用结构体数组来存储符号表。因为每个符号都有多种属性,用结构体可以将这些属性封装到一起。

    6.源程序代码

    main()

    {
       int i,j,ans;
       i = 5;
       j = 4;
       ans = i+j*5;
    }
    7.测试结果
    8.结果分析
      结果分析:将源程序读入后,经过词法分析程序,可以将源程序分割成一系列单词并将其划分出属性,同时进行词法检查。
  • 相关阅读:
    总有段迷惑的人生
    codepage的重要性【转】
    开通博客
    js 正则常用方法
    关于小程序scrollview组件添加enableflex后布局失效的解决方案
    关于小程序使用async/await报错regeneratorRuntime is not defined的解决方案
    IE6中,一个Button同时打开两个下载窗口,并且可以自动关闭
    Create User
    Oracle: import tables use .dmp file in PL/SQL Developer
    VS在进行调试时,不能调试的原因列举如下
  • 原文地址:https://www.cnblogs.com/lahblogs/p/3781075.html
Copyright © 2011-2022 走看看