基于C语言构造词法分析器+语法分析器完成编译原理实验

本文介绍了如何使用LL(1)分析法开发一个针对特定简单语言的词法分析器,实现对C/C++源程序的语法检查和结构分析。主要涉及词法分析和语法分析的实现,以及在VS2019开发环境中完成的实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

功能概述:
根据简单语言的词法和各单词符号种别码表,采用LL(1)分析法进行文法分析编写C或C++语言源程序,实现针对该简单语言的词法分析器,对词法分析程序所提供的单词序列进行语法检查和结构分析然后构造语法分析器。

所用知识:1.词法分析 2.语法分析
开发环境:VS2019

//main.c 主函数
#include<stdio.h>
#include<stdlib.h>
#include <iostream>
#include"def.h"
#include"funs.h"

using namespace std;
WORD scaner();
int main()
{
    int over = 1; WORD one = new Node;
    std::cout << "输入句子#号结束:";
    cin.getline(input,100);//scanf("%s",input);
    p_input = 0;
    cout << "输入的句子:";cout<<input<<"\n";
    fun(one);
    lr();
  
}

//funs.h文件  实现功能
void te(), fa(), ex(), st(), yu(), lr();
char ch, input[255] = "", token[255] = "";
int p_input, p_token, k = 0, legth = 0;
const char* rwtab[] = { "begin","if" ,"then","while","do","end","game over" };
LinkList * wd;
WORD scaner();

void fun(WORD one) {

    int over = 1;
    LinkList* head = (LinkList*)malloc(sizeof(LinkList));
    LinkList * q, * r;
    q = head; 
    head->next = NULL;
    r = head;
    wd = head; 
    while (over < 1000 && over != -1) {     
        one = scaner();
        LinkList *p = (LinkList*)malloc(sizeof(LinkList));
        p->num = one->typenum;
        p->w = one->word;
        p->next = NULL;
        q->next = p;
        q = p;
        if (one->typenum < 1000) std::cout << "(" << p->num << "," << p->w << ") ";
        over = one->typenum;
    }
    wd = head->next;
}
void ex() {
    te();
    while(wd->num==13||wd->num==14)
    {
        wd = wd->next;
        te();
    }
    return;
}

void fa() {
    if (wd->num == 10 || wd->num == 11) wd = wd->next;
    else if (wd->num == 27)
    {
        wd = wd->next;
        ex();
        if (wd->num == 28) wd = wd->next;
        else { std::cout << "\n)错误"; k = 1; }
    }
    else { std::cout << "\n表达式错误"; k = 1; } 
    return;
}

void te() {
    fa();
    while (wd->num==15||wd->num==16) 
    {
        wd = wd->next;
        fa();
    }
    return;
}

void st() {
    if (wd->num == 10)
    {
        wd = wd->next;
        if (wd->num == 18)
        {
            wd = wd->next;
            ex();

        }
        else { std::cout << "\n赋值号错误"; k = 1; }
    }
    else  {std::cout << "\n输出于醋错误"; k = 1;}
    return;
}
void yu() {
    st();
    while (wd->num==26)//;
    {
        wd = wd->next;
        st();
    
    }
    return;
}
void lr() {

    if (wd->num == 1)//begin
    {
        wd = wd->next;
        yu();
        if (wd->num == 6) //end
        {
            wd = wd->next;
            if ( k == 0) std::cout << "\nsuccess";

        }
        else { if (k != 1) std::cout << "\nend错误"; k = 1; }

    }
    else std::cout << "\nbegin错误";
    return;

}

char m_getch()
{
    ch = input[p_input];
    p_input = p_input + 1;
    return (ch);
}
void getbc()
{
    while (ch == ' ' || ch == 10)
    {
        ch = input[p_input];
        p_input = p_input + 1; //std::cout <<ch <<"//";
    }
}
void concat()
{
   
        token[p_token] = ch;
        p_token++;
        token[p_token] = '\0';
   
  
}
int letter()
{
    if (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z')
        return 1;
    else
        return 0;
}
int digit()
{
    if (ch >= '0' && ch <= '9')
        return 1;
    else
        return 0;
}
int reserve()
{
    int i = 0;
    while (strcmp(rwtab[i], "game over"))
    {
        if (!strcmp(rwtab[i], token))
        {
            return i + 1;
        }
        i = i + 1;
    }
    return 10;
}
void retract()
{
    p_input = p_input - 1;
}
WORD scaner() {

    WORD myword = new Node; 
    //char* t = (char*)calloc(legth, sizeof(char));
    //for (int i = 0; i <= 255;i++)   token[i] = ' ';  
    p_token = 0;
    m_getch();
    getbc(); 
   
    if (letter())
    {
        //legth = 0;
        while (letter() || digit())
        {   
            //legth++;
            concat();
            m_getch();
           
        }   
        //char* t = (char*)malloc(legth * sizeof(char));
        retract();
       // for (int i = 0; i <= legth - 1; i++) { t[i] = token[i]; }
        myword->typenum = reserve();
        myword->word = token;
        return(myword);
    }

    else if (digit())
    {
        //legth = 0;
        while (digit())
        {
           // legth++;
            concat();
            m_getch();
            
        }
        retract();
        //char* t = (char*)malloc(legth * sizeof(char));  for (int i = 0; i <= legth - 1; i++) std::cout <<t[i]<<"+";
        //for (int i = 0; i <= legth-1; i++)  t[i] = token[i];
        myword->typenum = 11;
        myword->word = token;
        return(myword);
    }

    else switch (ch)
    {

    case '=':   m_getch();
        if (ch == '=')
        {
            myword->typenum = 25;
            myword->word = "==";
            return(myword);
        }
        retract();
        myword->typenum = 25;
        myword->word = "=";
        return(myword);
        break;
    case '+':   myword->typenum = 13;
        myword->word = "+";
        return(myword);
        break;
    case '-':   myword->typenum = 14;
        myword->word = "-";
        return(myword);
        break;
    case '*':   myword->typenum = 15;
        myword->word = "*";
        return(myword);
        break;
    case '/':   myword->typenum = 16;
        myword->word = "/";
        return(myword);
        break;
    case '(':   myword->typenum = 27;
        myword->word = "(";
        return(myword);
        break;

    case ')':   myword->typenum = 28;
        myword->word = ")";
        return(myword);
        break;
    case ':':  m_getch();
        if (ch == '=')
        {
            myword->typenum = 18;
            myword->word = ":=";
            return myword;
        }
        retract();
        myword->typenum = 17;
        myword->word = ":";
        return(myword);
        break;
    case ';':   myword->typenum = 26;
        myword->word = ";";
        return(myword);
        break;
    case '#':   myword->typenum = 0;
        myword->word = "#";
        return(myword);
        break;
    case '>':   m_getch();
        if (ch == '=')
        {
            myword->typenum = 24;
            myword->word = ">=";
            return(myword);
        }
        retract();
        myword->typenum = 23;
        myword->word = ">";
        return(myword);
        break;
    case '<':   m_getch();
        if (ch == '=')
        {
            myword->typenum = 22;
            myword->word = "<=";
            return(myword);
        }
        retract();
        myword->typenum = 20;
        myword->word = "<";
        return(myword);
        break;

    case '\0':   myword->typenum = 1000;
        myword->word = "OVER";
        return(myword);
        break;

    default:    myword->typenum = -1;
        myword->word = "ERROR";
        return(myword);
        break;
    }
}



//def.h文件 定义结构体
typedef struct {
    int typenum;
    char *word;
}Node,*WORD;

typedef struct HNode{
    struct HNode *next;
    int num;
    char* w;
}LinkList;

运行结果:
符合语法
如图根据语法c:=0后面不能跟;,所以报出输出语句错误提示
这里没有强制要求以#结束,且功能较为简单。此处用C下一篇使用Java编写程序。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值