zoukankan      html  css  js  c++  java
  • 作业5 词法分析程序的设计与实现

    词法分析程序(Lexical Analyzer)要求:

    - 从左至右扫描构成源程序的字符流

    -  识别出有词法意义的单词(Lexemes

    -  返回单词记录(单词类别,单词本身)

    -  滤掉空格

    -  跳过注释

    -  发现词法错误

    程序结构:

    输入:字符流(什么输入方式,什么数据结构保存)

    处理:

    –遍历(什么遍历方式)

    –词法规则

    输出:单词流(什么输出形式)

    –二元组

    单词类别:

    1.标识符(10)

    2.无符号数(11)

    3.保留字(一词一码)

    4.运算符(一词一码)

    5.界符(一词一码)

    单词符号

    种别码

    单词符号

    种别码

    main

    1

    ,

    13

    int

    2

    ;

    14

    if

    3

    (

    15

    else

    4

    )

    16

    while

    5

    {

    17

    do

    6

    }

    18

    7

    +

    19

    8

    -

    20

    !=

    9

    *

    21

    >=

    10

    /

    22

    <=

    11

    =

    23

    ==

    12

     

     

      1 #include <iostream>
      2 #include<stdio.h>
      3 #include<string.h>
      4 #include<stdlib.h>
      5 using namespace std;
      6  
      7 //关键字 
      8 string key[6]={"main","int","if","else","while","do"}; 
      9 
     10 //关键字的种别码
     11 int keyNum[6]={1,2,3,4,5,6}; 
     12 
     13 //运算符和界符 
     14 string symbol[17]={"<",">","!=",">=","<=","==",",",";","(",")","{","}","+","-","*","/","="};
     15 
     16 //运算符和界符的种别码 
     17 int symbolNum[17]={7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23};
     18 
     19 //存放文件取出的字符 
     20 string letter[1000];
     21 
     22 int length; //保存程序中字符的数目 
     23 int num;
     24 
     25 //判断运算符和界符  
     26 int isSymbol(string s){ 
     27      int i;
     28      for(i=0;i<17;i++){
     29           if(s==symbol[i])
     30                return symbolNum[i]; 
     31      }
     32      return 0;
     33 } 
     34  
     35 //判断是否为数字 
     36 bool isNum(string s){
     37      if(s>="0" && s<="9")
     38           return true;
     39      return false;
     40 }
     41  
     42 //判断是否为字母 
     43 bool isLetter(string s){
     44      if(s>="a" && s<="z")
     45           return true;
     46      return false;
     47 }
     48  
     49 //判断是否为关键字,是返回种别码 
     50 int isKeyWord(string s){
     51      int i;
     52      for(i=0;i<6;i++){
     53           if(s==key[i])
     54                return keyNum[i];
     55      }
     56      return 0;
     57 }
     58  
     59 //返回单个字符的类型 
     60 int typeword(string str){
     61      if(str>="a" && str<="z") // 字母 
     62           return 1;
     63  
     64      if(str>="0" && str<="9") //数字 
     65           return 2;
     66  
     67      if(str==">"||str=="="||str=="<"||str=="!"||str==","||str==";"||str=="("||str==")"||str=="{"||str=="}"||str=="+"||str=="-"||str=="*"||str=="/") //判断运算符和界符 
     68           return 3; 
     69 }
     70 //标识符的连接 
     71 string identifier(string s,int n){
     72      int j=n+1;
     73      int flag=1;
     74  
     75      while(flag){
     76           if(isNum(letter[j]) || isLetter(letter[j])){
     77                s=(s+letter[j]);
     78                if(isKeyWord(s)){
     79                 j++;
     80                 num=j;
     81                 return s;
     82                }
     83                j++;
     84           }else{
     85                flag=0;
     86           }
     87      } 
     88  
     89      num=j;
     90      return s;
     91 }
     92 
     93 //符号和界符的连接  
     94 string symbolStr(string s,int n){
     95      int j=n+1;
     96      string str=letter[j];
     97      if(str==">"||str=="="||str=="<"||str=="!") {
     98           s=(s+letter[j]);
     99           j++;
    100      }
    101      num=j;
    102      return s;
    103 }
    104 
    105 //数字的连接 
    106 string Number(string s,int n){
    107      int j=n+1;
    108      int flag=1;
    109  
    110      while(flag){
    111           if(isNum(letter[j])){
    112                s=(s+letter[j]);
    113                j++;
    114           }else{
    115                flag=0;
    116           }
    117      }
    118  
    119      num=j;
    120      return s;
    121 }
    122 
    123 //输出 
    124 void print(string s,int n){
    125      cout<<"("<<s<<","<<n<<")"<<endl;
    126 }
    127 
    128 //取单词 
    129 void TakeWord(){  
    130      int k;
    131  
    132      for(num=0;num<length;){
    133           string str1,str;
    134           str=letter[num];
    135           k=typeword(str);
    136           switch(k){
    137                case 1:{
    138                  str1=identifier(str,num);
    139                  if(isKeyWord(str1))
    140                       print(str1,isKeyWord(str1));
    141                  else
    142                       print(str1,0);
    143                  break;
    144             }
    145  
    146                case 2:{
    147                  str1=Number(str,num);
    148                  print(str1,24);
    149                  break;
    150             }
    151  
    152                case 3:{
    153                  str1=symbolStr(str,num);
    154                  print(str1,isSymbol(str1));
    155                  break; 
    156             }
    157  
    158           }
    159      } 
    160 }
    161  
    162 int main(){
    163      char w;
    164      int i,j;
    165  
    166      freopen("s.txt","r",stdin);
    167  
    168      length=0;
    169      while(cin>>w){
    170           if(w!=' '){
    171                letter[length]=w;
    172                length++;
    173           } //去掉程序中的空格
    174      }
    175  
    176      TakeWord();
    177  
    178      fclose(stdin);//关闭文件 
    179      return 0;
    180 }

    实验文本:

     实验结果:

     该实验的代码是参考网上代码修改的,逻辑大概能理清,但是没有实现跳过注释的功能。

  • 相关阅读:
    JS动态计算rem
    Vue数据双向绑定原理
    NOI2019 退役记
    友情链接
    算法博客总结
    总结各类错误(always online)
    学习笔记:powerful number求积性函数前缀和
    LOJ#2409. 「THUPC 2017」小 L 的计算题 / Sum(生成函数)
    多项式简单操作
    LOJ #3103. 「JSOI2019」节日庆典
  • 原文地址:https://www.cnblogs.com/m2362563619/p/11656569.html
Copyright © 2011-2022 走看看