编译原理 实验2 词法分析(C/C++版)

任务描述

使用C/C++语言编写PL/0编译程序的词法分析程序。 需要注意的点: (1)识别非法字符:如 @ 、 & 和 ! 等; (2)识别非法单词:数字开头的数字字母组合; (3)标识符和无符号整数的长度不超过8位; (4)能自动识别并忽略/* */及//格式的注释信息; (5)词法分析过程中遇到错误后能继续往下识别,并输出错误信息。

编程要求

完成上述编程任务,将C/C++语言源程序复制粘贴到右侧代码编辑器,点击“评测”按钮,运行程序,系统会自动进行结果对比。

测试说明

平台会对你编写的代码进行测试:

测试输入:

  1. const a = 10;
  2. var b, c;
  3. procedure fun1;
  4. if a <= 10 then
  5. begin
  6. c := b + a;
  7. end;
  8. begin
  9. read(b);
  10. while b # 0 do
  11. begin
  12. call fun1;
  13. write(2 * c);
  14. read(b);
  15. end
  16. end.

预期输出:

 
  1. (保留字,const)
  2. (标识符,a)
  3. (运算符,=)
  4. (无符号整数,10)
  5. (界符,;)
  6. (保留字,var)
  7. (标识符,b)
  8. (界符,,)
  9. (标识符,c)
  10. (界符,;)
  11. (保留字,procedure)
  12. (标识符,fun1)
  13. (界符,;)
  14. (保留字,if)
  15. (标识符,a)
  16. (运算符,<=)
  17. (无符号整数,10)
  18. (保留字,then)
  19. (保留字,begin)
  20. (标识符,c)
  21. (运算符,:=)
  22. (标识符,b)
  23. (运算符,+)
  24. (标识符,a)
  25. (界符,;)
  26. (保留字,end)
  27. (界符,;)
  28. (保留字,begin)
  29. (保留字,read)
  30. (界符,()
  31. (标识符,b)
  32. (界符,))
  33. (界符,;)
  34. (保留字,while)
  35. (标识符,b)
  36. (运算符,#)
  37. (无符号整数,0)
  38. (保留字,do)
  39. (保留字,begin)
  40. (保留字,call)
  41. (标识符,fun1)
  42. (界符,;)
  43. (保留字,write)
  44. (界符,()
  45. (无符号整数,2)
  46. (运算符,*)
  47. (标识符,c)
  48. (界符,))
  49. (界符,;)
  50. (保留字,read)
  51. (界符,()
  52. (标识符,b)
  53. (界符,))
  54. (界符,;)
  55. (保留字,end)
  56. (保留字,end)
  57. (界符,.)

测试输入:

 
  1. const 2a = 123456789;
  2. var b, c;
  3. //单行注释
  4. /*
  5. * 多行注释
  6. */
  7. procedure function1;
  8. if 2a <= 10 then
  9. begin
  10. c := b + a;
  11. end;
  12. begin
  13. read(b);
  14. while b @ 0 do
  15. begin
  16. call function1;
  17. write(2 * c);
  18. read(b);
  19. end
  20. end.

预期输出:

 
  1. (保留字,const)
  2. (非法字符(串),2a,行号:1)
  3. (运算符,=)
  4. (无符号整数越界,123456789,行号:1)
  5. (界符,;)
  6. (保留字,var)
  7. (标识符,b)
  8. (界符,,)
  9. (标识符,c)
  10. (界符,;)
  11. (保留字,procedure)
  12. (标识符长度超长,function1,行号:10)
  13. (界符,;)
  14. (保留字,if)
  15. (非法字符(串),2a,行号:11)
  16. (运算符,<=)
  17. (无符号整数,10)
  18. (保留字,then)
  19. (保留字,begin)
  20. (标识符,c)
  21. (运算符,:=)
  22. (标识符,b)
  23. (运算符,+)
  24. (标识符,a)
  25. (界符,;)
  26. (保留字,end)
  27. (界符,;)
  28. (保留字,begin)
  29. (保留字,read)
  30. (界符,()
  31. (标识符,b)
  32. (界符,))
  33. (界符,;)
  34. (保留字,while)
  35. (标识符,b)
  36. (非法字符(串),@,行号:17)
  37. (无符号整数,0)
  38. (保留字,do)
  39. (保留字,begin)
  40. (保留字,call)
  41. (标识符长度超长,function1,行号:19)
  42. (界符,;)
  43. (保留字,write)
  44. (界符,()
  45. (无符号整数,2)
  46. (运算符,*)
  47. (标识符,c)
  48. (界符,))
  49. (界符,;)
  50. (保留字,read)
  51. (界符,()
  52. (标识符,b)
  53. (界符,))
  54. (界符,;)
  55. (保留字,end)
  56. (保留字,end)
  57. (界符,.)

代码展示:

#include<bits/stdc++.h>
using namespace std;
map<string,int> B, Y; 
map<char,int> J, y; 
string s;
int F;  
int main()
{
    B["const"]=B["var"]=B["procedure"]=B["begin"]=B["end"]=B["odd"]=B["if"]=B["then"]=B["call"]=B["while"]=B["do"]=B["read"]=B["write"]=1; 
    Y["+"]=Y["-"]=Y["*"]=Y["/"]=Y["<"]=Y["<="]=Y[">"]=Y[">="]=Y["#"]=Y["="]=Y[":="]=1; 
    y['+']=y['-']=y['*']=y['/']=y['<']=y['>']=y['=']=y['#']=y[':']=1;
    J['(']=J[')']=J[',']=J[';']=J['.']=1; 
    string s1 = "//", s2 = "/*", s3 = "*/", str;
    for(int id = 1; getline( cin, s); id++) {
        int f = 0; 
        for(int i=0; s[i]!='\0'; i++) {
            while(s[i]!='\0' && (s[i]==' ' || s[i]=='\t')) i++;
            int f1 = 0, f2 = 0, f3 = 0, f4 = 0, flog = 0;
            int j1 = i, j2 = i; 
            if(!((s[i]>='0'&&s[i]<='9') || (s[i]>='a'&&s[i]<='z') || (s[i]>='A'&&s[i]<='Z') || y[s[i]]==1 || J[s[i]]==1)) flog = 1; 
            while(s[j1]!='\0' && ((s[j1]>='0'&&s[j1]<='9') || (s[j1]>='a'&&s[j1]<='z') || (s[j1]>='A'&&s[j1]<='Z')) ) {
                if( s[j1]>='0'&& s[j1]<='9' ) f1 = 1; 
                else f2 = 1; 
                j1 ++;
            }
            while(s[j2]!='\0' && y[ s[j2] ] == 1) f3 = 1, j2 ++; 
            if(J[ s[i] ] == 1) f4 = 1; 
            if(f1 || f2) str =  s.substr( i, j1-i); 
            if(f1 == 1 && f2 == 0 && !f && !F) { 
                if(str.size() <= 8)  cout<<"(无符号整数,"<<str<<")"<<endl;
                else cout<<"(无符号整数越界,"<<str<<",行号:"<<id<<")"<<endl;
            }
            else if(f2 == 1 && B[str] != 1 && !f && !F) { 
                if(s[i]>='0' && s[i]<='9') cout<<"(非法字符(串),"<<str<<",行号:"<<id<<")"<<endl; 
                else if(str.size() <= 8) cout<<"(标识符,"<<str<<")"<<endl;
                else cout<<"(标识符长度超长,"<<str<<",行号:"<<id<<")"<<endl;
            }
            else if(f2 == 1 && B[str] == 1 && !f && !F) cout<<"(保留字,"<<str<<")"<<endl; 
            else if( f3 == 1) { 
                str = s.substr( i, j2-i); 
                if(str == s1) f = 1; 
                else if(str == s2) F = 1; 
                else if(str == s3) F = 0; 
                else if(!f && !F)
                    cout<<"(运算符,"<<str<<")"<<endl;
            }
            else if(f4 == 1 && !f && !F) 
                cout<<"(界符,"<<s[i]<<")"<<endl;
            else if(flog == 1 && !f && !F) cout<<"(非法字符(串),"<<s[i]<<",行号:"<<id<<")"<<endl; 
            if(j1 != i) i = j1 - 1;
            else if(j2 != i) i = j2 - 1; 
        }
    }
    return 0;
 }

 

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值