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.结果分析
      结果分析:将源程序读入后,经过词法分析程序,可以将源程序分割成一系列单词并将其划分出属性,同时进行词法检查。
  • 相关阅读:
    背水一战 Windows 10 (61)
    背水一战 Windows 10 (60)
    背水一战 Windows 10 (59)
    背水一战 Windows 10 (58)
    背水一战 Windows 10 (57)
    背水一战 Windows 10 (56)
    背水一战 Windows 10 (55)
    背水一战 Windows 10 (54)
    背水一战 Windows 10 (53)
    背水一战 Windows 10 (52)
  • 原文地址:https://www.cnblogs.com/lahblogs/p/3781075.html
Copyright © 2011-2022 走看看