首页 > 编程语言 >用 C/C++ 编写一个 C 语言的语法分析器程序

用 C/C++ 编写一个 C 语言的语法分析器程序

时间:2023-12-09 14:45:40浏览次数:44  
标签:cnt 语法分析 int C++ return ++ prog 编写 ptr

任务描述

本关任务:用 C/C++ 编写一个 C 语言的语法分析器程序。

相关知识

为了完成本关任务,你需要掌握:1.DFA NFA,2.C/C++ 编程语言基础。3. C 语言的基本结构知识

自动机

在编译原理课堂上已经教授了大家相关知识。在完成本实训前,一定要先设计相关自动机,再开始相关功能的实现。切勿,想到哪里,就编程到哪里,以至于代码一团糟,可维护性与可读性都很差。

C/C++

本实训涉及函数、结构体,标准流输入输出,字符串等操作

C语言基本结构

C 语言子集。 第一类:标识符 第二类:常数 第三类:保留字(32)

auto break case char const continue
default do double else enum extern
float for goto if int long
register return short signed sizeof static
struct switch typedef union unsigned void
volatile while

第四类:界符 /*// () { }[ ]" "' 等 第五类:运算符 <<=>>==+-*/^

**所有语言元素集合在 c_keys.txt **文件中。 注意,C_key.txt中缺少“//注释”的情况,请也映射到编号79!

auto    1
break    2
case    3
char    4
const    5
continue    6
default    7
do    8
double    9
else    10
enum    11
extern    12
float    13
for    14
goto    15
if    16
int    17
long    18
register    19
return    20
short    21
signed    22
sizeof    23
static    24
struct    25
switch    26
typedef    27
union    28
unsigned    29
void    30
volatile    31
while    32
-    33
--    34
-=    35
->    36
!    37
!=    38
%    39
%=    40
&    41
&&    42
&=    43
(    44
)    45
*    46
*=    47
,    48
.    49
/    50
/=    51
:    52
;    53
?    54
[    55
]    56
^    57
^=    58
{    59
|    60
||    61
|=    62
}    63
~    64
+    65
++    66
+=    67
<    68
<<    69
<<=    70
<=    71
=    72
==    73
>    74
>=    75
>>    76
>>=    77
"    78
/*注释*/    79
常数    80
标识符    81

编程要求

请仔细阅读该部分

输入

样例输入放在prog.txt文件中 样例1输入

int main()
{
  printf("HelloWorld");
  return 0;
}

 

输出

输出要满足以下要求

  1. 计数: <符号名,符号标号>

注意,冒号后边有一个空格 样例1输出

1: <int,17>
2: <main,81>
3: <(,44>
4: <),45>
5: <{,59>
6: <printf,81>
7: <(,44>
8: <",78>
9: <HelloWorld,81>
10: <",78>
11: <),45>
12: <;,53>
13: <return,20>
14: <0,80>
15: <;,53>
16: <},63>

 

注意,输出不能有多余的空格,回车等符号。请注意样例输出最后一行后是没有回车的!输出的符号都是英文的半角符号。

ERROR

本实训不考虑错误处理,我保证输入的所有代码块是合法的 C 语言代码。


开始你的任务吧,祝你成功!

 

 

// C语言词法分析器
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <string>
#include <fstream>
#include <sstream>
#include <vector>
using namespace std;
string keyword[40]={"","auto","break","case","char","const","continue",
"default","do","double","else","enum" ,"extern","float","for","goto",
"if","int","long","register","return","short","signed","sizeof",
"static","struct"," switch","typedef","union","unsigned","void",
"volatile","while"};
string mark[50]={"","-","--","-=","->","!","!=","%","%=","&","&&",
"&=","(",")","*","*=",",",".","/","/=",":",";","?","[","]","^",
"^=","{","|","||","|=","}","~","+","++","+=","<","<<","<<=","<=",
"=","==",">",">=",">>",">>=","\""};
string prog;
int cnt=1;
/* 不要修改这个标准输入函数 */
void read_prog(string& prog)
{
    char c;
    while(scanf("%c",&c)!=EOF){
        prog += c;
    }
}
/* 判断函数 */
bool isnum(char c)
{
    if(c >= '0' && c<= '9')
        return true;
    return false;
}
bool isletter(char c)
{
    if( (c>='a' && c<='z') || (c>='A' && c<='Z'))
        return true;
    return false;    
}
bool iskeyword(string s)
{
    for(int i=1;i<=32;i++)
        if(s==keyword[i])
        {
            if(cnt!=1) cout<<endl; 
            cout<<cnt<<": "<<"<"<<s<<","<<i<<">"; 
            cnt++;
            return true;
        }
            
    return false;    
}
/* 查找函数 */
int numtoken(int l)
{
    //找出整个数字 
    int r=l;
    while(isnum(prog[r]))
        r++;
    string s = prog.substr(l,r-l);
    //输出 
    if(cnt!=1) cout<<endl; 
    cout<<cnt<<": "<<"<"<<s<<","<<80<<">"; 
    cnt++;
    
    return r;
}
int lettertoken(int l)
{
    //找出整个单词 
    int r=l;
    while(isletter(prog[r]) || isnum(prog[r]))
        r++;
    string s = prog.substr(l,r-l);
    
    if(iskeyword(s))
        return r;
    //输出 
    if(cnt!=1) cout<<endl; 
    cout<<cnt<<": "<<"<"<<s<<","<<81<<">"; 
    cnt++;
    return r;
}
int note1(int l)// //注释 
{
    int r=l;
    while(prog[r]!='\n')
        r++;
    string s = prog.substr(l,r-l);
    if(cnt!=1) cout<<endl; 
    cout<<cnt<<": "<<"<"<<s<<","<<79<<">"; 
    cnt++;
    return r;
}
int note2(int l)// /*注释 
{
    int r=l;
    while(1)
    {
        if(prog[r]=='*' && prog[r+1]=='/')
            break;
        r++;
    }
    r=r+2;
    string s = prog.substr(l,r-l);
    if(cnt!=1) cout<<endl; 
    cout<<cnt<<": "<<"<"<<s<<","<<79<<">"; 
    cnt++;
    return r;
}
int operatortoken(int l)
{
    for(int j=3;j>=1;j--)
        for(int i=1;i<=46;i++)
            if(prog.substr(l,j)==mark[i])
            {
                if(cnt!=1) cout<<endl; 
                cout<<cnt<<": "<<"<"<<prog.substr(l,j)<<","<<i+32<<">"; 
                cnt++;
                return l+j;
            }
    return l+1;
}

void Analysis()
{
    read_prog(prog);
    /* 骚年们 请开始你们的表演 */
    int ptr=0,k=0;
    while(ptr<prog.length()){
        while(prog[ptr]==' ' || prog[ptr]=='\n')
            ptr++;
        if(ptr>=prog.length()) break;
        if(isnum(prog[ptr]))//常数 
            ptr=numtoken(ptr);
        else if(isletter(prog[ptr]))//关键字和变量名 
            ptr=lettertoken(ptr);
        else
        {
            //两种注释 
            if(prog[ptr]=='/' && prog[ptr+1]=='/')
                ptr=note1(ptr);
            else if(prog[ptr]=='/' && prog[ptr+1]=='*')
                ptr=note2(ptr);    
            else if(prog[ptr]=='%' && isletter(prog[ptr+1]) )
            {
                if(cnt!=1) cout<<endl; 
                cout<<cnt<<": "<<"<"<<prog.substr(ptr,2)<<","<<81<<">"; 
                cnt++;
                ptr=ptr+2;
            }
            else
                ptr=operatortoken(ptr);
        }
    }
}
int main()
{
    Analysis();
    return 0;
 } 

 

标签:cnt,语法分析,int,C++,return,++,prog,编写,ptr
From: https://www.cnblogs.com/hfang/p/17890927.html

相关文章

  • C++ Qt开发:Qt的安装与配置
    Qt是一种C++编程框架,用于构建图形用户界面(GUI)应用程序和嵌入式系统。Qt由Qt公司(前身为Nokia)开发,提供了一套跨平台的工具和类库,使开发者能够轻松地创建高效、美观、可扩展的应用程序。其被广泛用于开发桌面应用程序、嵌入式系统、移动应用程序等。无论是初学者还是经验丰富的开发者......
  • Qt6 c++教程2 Qt Creator简介
    2QtCreator简介QtCreator是Qt自带的集成开发环境(IDE),用于跨平台应用程序开发。在本章中,您将学习QtCreator集成开发环境的基础知识,并了解集成开发环境的用户界面(UI)。我们还将了解如何在QtCreator中创建和管理项目。本Qt模块包括使用QtCreator开发一个简单的Qt应用程序、......
  • C++基础 -1- 标准输入输出
    ———————标准输入输出——————— ......
  • c++ 什么情况下需要new
    在C++中,new关键字主要用于动态内存分配。以下是一些可能需要使用new的情况:复杂类型:对于复杂类型,如自定义的类类型,通常需要使用new进行动态内存分配。大量内存空间:当你需要大量的内存空间时,比如你需要一个包含10000个int的数组,这时候你就需要使用new。内存大小未知:有时......
  • 【C++ mutable使用】
    什么是mutable关键字?mutable被用于修饰类的成员变量。当一个成员变量被声明为mutable时,它允许在const成员函数内部被修改,即使对象本身是常量。为什么使用mutable?缓存数据:在对象内部维护一个缓存,但不希望影响对象的常量性质时,可以使用mutable来标记缓存变量。记录状态信息......
  • Linux内核开发流程指南 - 4. 编写正确的代码【ChatGPT】
    https://www.kernel.org/doc/html/v6.6/process/4.Coding.html4.编写正确的代码虽然坚实且以社区为导向的设计过程有很多值得说的地方,但任何内核开发项目的证明都在于最终的代码。其他开发人员将审查这些代码,并将其合并(或不合并)到主线树中。因此,代码的质量将决定项目的最终成......
  • Linux内核开发流程指南 - 5. 编写正确的代码【ChatGPT】
    https://www.kernel.org/doc/html/v6.6/process/5.Posting.html5.提交补丁迟早会有一个时刻,你的工作准备好被提交给社区审查,并最终被合并到主线内核中。毫不奇怪,内核开发社区已经形成了一套用于提交补丁的惯例和程序,遵循这些规定将使所有相关人员的生活变得更加轻松。本文将......
  • c++ 程序的内存分配
    C++程序在执行时,将内存大致分为以下几个区域:栈:系统自动分配的空间,只要不特殊声明,就定义在栈区,函数的区域也在栈上。栈是向下增长的。(const在栈里)堆:使用动态内存分配的方式可以申请堆空间,用完要手动释放。newmalloc全局区:全局变量、静态变量(static),生命周期是程序整个运行过......
  • C/C++ 实现动态资源文件释放
    当我们开发Windows应用程序时,通常会涉及到使用资源(Resource)的情况。资源可以包括图标、位图、字符串等,它们以二进制形式嵌入到可执行文件中。在某些情况下,我们可能需要从可执行文件中提取自定义资源并保存为独立的文件。在这篇博客文章中,我们将讨论如何使用C++和WinAPI实现这个目......
  • JetBrains CLion 2023.3 (macOS, Linux, Windows) - C 和 C++ 跨平台 IDE
    JetBrainsCLion2023.3(macOS,Linux,Windows)-C和C++跨平台IDE请访问原文链接:https://sysin.org/blog/jb-clion-2023/,查看最新版。原创作品,转载请保留出处。作者主页:sysin.orgJetBrainsCLion-C和C++跨平台IDECLion2022现已发布。查看最新变化用于强大语......