zoukankan      html  css  js  c++  java
  • 编写词法分析器

    词法分析器功能

    输入源程序、输出单词符号(其表示形式为:(单词种别,单词自身的值)

    预处理:删除注释,删除续换行符,换行符,TAB和空格

    词法分析器的设计

    (1)给出程序设计语言的单词规范——单词表

    单词符号

    种别编码

    标识符

    0

    main

    1

    int

    2

    If

    3

    else

    4

    while

    5

    do

    6

    7

    8

    !=

    9

    >=

    10

    <=

    11

    ==

    12

    ,

    13

    ;

    14

    (

    15

    )

    16

    {

    17

    }

    18

    +

    19

    -

    20

    *

    21

    /

    22

    =

    23

    常数(数)

    24

    2)对照单词表设计识别该单词所有单词的状态转换图

    状态转换图实质上是程序流程图,每个状态结对应一小段程序。

    程序思路:

    (1)预处理:去掉程序中的空格和注释

    (2)取出字符进行单词符号的识别并进行相应的处理

    (3)输出词法分析结果

    3)根据状态转换图编写词法分析器

      1 #include<iostream>
      2 #include<stdio.h>
      3 #include<string.h>
      4 using namespace std;
      5 
      6 int keyNum[6]= {1,2,3,4,5,6};//存储关键字的种别编码
      7 string key[6]= {"main","int","if","else","while","do"}; //存储关键字数组 
      8 int symbolNum[17]= {7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23};//存储运算符和界符的种别码 
      9 string symbol[17]= {"<",">","!=",">=","<=","==",",",";","(",")","{","}","+","-","*","/","="};//存储运算符和界符数组 
     10 string letter[1000];//存储从文件中取出的字符
     11 string words[1000];//将字符转换为单词
     12 int length; //程序中字符的数目
     13 int num;//当前遍历到的字符下标 
     14 
     15 int isSymbol(string s)  //判断运算符和界符
     16 {
     17     int i;
     18     for(i=0; i<17; i++)
     19     {
     20         if(s==symbol[i])
     21             return symbolNum[i];
     22     }
     23     return 0;
     24 }
     25 
     26 bool isNum(string s)//判断是否为数字
     27 {
     28     if(s>="0" && s<="9")
     29         return true;
     30     return false;
     31 }
     32 
     33 bool isLetter(string s)//判断是否为字母
     34 {
     35     if(s>="a" && s<="z")
     36         return true;
     37     return false;
     38 }
     39 
     40 int isKeyWord(string s)//判断是否为关键字,是返回种别码
     41 {
     42     int i;
     43     for(i=0; i<6; i++)
     44     {
     45         if(s==key[i])
     46             return keyNum[i];
     47     }
     48     return 0;
     49 }
     50 
     51 int typeword(string str)//返回单个字符的类型
     52 {
     53     if(str>="a" && str<="z") // 字母
     54         return 1;
     55 
     56     if(str>="0" && str<="9") //数字
     57         return 2;
     58 
     59     if(str==">"||str=="="||str=="<"||str=="!"||str==","||str==";"||str=="("||str==")"||str=="{"||str=="}"||str=="+"||str=="-"||str=="*"||str=="/") //判断运算符和界符
     60         return 3;
     61 }
     62 
     63 string identifier(string s,int n) //连接标识符
     64 {
     65     int j=n+1;
     66     int flag=1;
     67 
     68     while(flag)
     69     {
     70         if(isNum(letter[j]) || isLetter(letter[j]))
     71         {
     72             s=(s+letter[j]).c_str();
     73             if(isKeyWord(s))
     74             {
     75                 j++;
     76                 num=j;
     77                 return s;
     78             }
     79             j++;
     80         }
     81         else//运算符等操作符
     82         {
     83             flag=0;
     84         }
     85     }
     86 
     87     num=j;
     88     return s;
     89 }
     90 
     91 string symbolStr(string s,int n) //连接符号与界符
     92 {
     93     int j=n+1;
     94     string str=letter[j];
     95     if(str==">"||str=="="||str=="<"||str=="!")
     96     {
     97         s=(s+letter[j]).c_str();
     98         j++;
     99     }
    100     num=j;
    101     return s;
    102 }
    103 
    104 string Number(string s,int n)//连接数字 
    105 {
    106     int j=n+1;
    107     int flag=1;
    108 
    109     while(flag)
    110     {
    111         if(isNum(letter[j]))
    112         {
    113             s=(s+letter[j]).c_str();
    114             j++;
    115         }
    116         else
    117         {
    118             flag=0;
    119         }
    120     }
    121 
    122     num=j;
    123     return s;
    124 }
    125 
    126 void print(string s,int n)
    127 {
    128     cout<<"("<<s<<","<<n<<")"<<endl;
    129 }
    130 
    131 void TakeWord()  //对letter数组中的字符进行分析 
    132 {
    133     int k;
    134 
    135     for(num=0; num<length;)
    136     {
    137         string str1,str;
    138         str=letter[num];
    139         k=typeword(str);//分析字符的类型 
    140         switch(k)
    141         {
    142         case 1: //表明该字符为字母 
    143         {
    144             str1=identifier(str,num);
    145             if(isKeyWord(str1))//输出关键字 
    146                 print(str1,isKeyWord(str1));
    147             else //输出标识符 
    148                 print(str1,0);
    149             break;
    150         }
    151         case 2://表明该字符为数字
    152         {
    153             str1=Number(str,num);
    154             print(str1,24);//输出常数 
    155             break;
    156         }
    157 
    158         case 3://表明该字符为运算符和界符
    159         {
    160             str1=symbolStr(str,num);
    161             print(str1,isSymbol(str1));//输出运算符和界符 
    162             break;
    163         }
    164         }
    165     }
    166 }
    167 
    168 int main()
    169 {
    170     freopen("E:\input.txt","r",stdin);
    171     freopen("E:\output.txt","w",stdout); 
    172     int i,j,flag=0;
    173     char w,front,aa=' ';//aa存前一个的'/' 
    174     length=0;
    175     while(cin>>w)//预处理:去掉程序中的空格和注释 
    176     {
    177         if((w=='/')&&(front=='/')){ //注释//开始判断条件
    178             flag=1;
    179         }
    180         else if((w=='*')&&(front=='/')){ //注释/*开始判断条件
    181             flag=2;
    182         }
    183         else if((flag==1)&&(w=='
    ')){ //注释//结束判断条件 
    184         //cout<<"------------"<<endl;
    185             flag=0;
    186         }
    187         else if((flag==2)&&(w=='/')){ //注释/*结束判断条件
    188         //cout<<"------------"<<endl;
    189             flag=0;
    190         }
    191         else if((w!=' ')&&(flag==0))
    192         {
    193             int outflag=0;
    194             if(aa=='/'){ //表示'/'并不是注释的组成部分,则输出存的前一个'/' 
    195                 letter[length]=w;
    196                 length++;
    197                 aa=' ';
    198                 outflag=1;
    199             }
    200             if(w=='/') aa=w;
    201             else{
    202                 if(outflag==0)//前面没输出 
    203                 {
    204                     letter[length]=w;
    205                     length++;
    206                 }
    207             }
    208         } 
    209         front=w;
    210     }
    211     //
    212     TakeWord();//从letter数组中取出字符进行分析
    213 
    214     fclose(stdin);//关闭文件
    215     fclose(stdout);
    216     return 0;
    217 }

    (4)结果

    输入程序:

    /*compare a and b then output the poccess result*/
    int main()
    {
        int a,b;
        a=5;
        b=4;
        if(a>=b)
        {
            a=a-b;
        }
        else
        {
            a=a+b;
        }
    }

     输出的词法分析结果:

     

  • 相关阅读:
    RabbitMQ学习笔记
    Eclipse下JRebel的安装和基本使用
    通过HTTP响应头让浏览器自动刷新
    CentOS6.5安装Jenkins
    Windows快捷操作技巧
    关于代码压缩混淆加密整理;
    一款优雅的小程序拖拽排序组件实现
    记一次 Mac CA证书 问题
    微信小程序-Swiper和下拉刷新组件
    WeUI Picker组件 源代码分析
  • 原文地址:https://www.cnblogs.com/Aiahtwo/p/12804065.html
Copyright © 2011-2022 走看看