PL/0语言 自上而下语法分析 递归下降分析

一、简介

PL0 语言功能简单、结构清晰、可读性强,而又具备了一般高级程序设计语言的必须部分,因而 PL0 语言的编译程序能充分体现一个高级语言编译程序实现的基本方法和技术。
分析对象〈算术表达式〉的 BNF 定义如下:
<表达式> ::= [+|-]<项>{<加法运算符> <项>}
<项> ::= <因子>{<乘法运算符> <因子>}
<因子> ::= <标识符>|<无符号整数>| ‘(’<表达式>‘)’
<加法运算符> ::= +|-
<乘法运算符> ::= *|/

二、设计思想
1、表达式的文法

按照扩充的巴克斯范式书写:
E -> [+|-]T{AT}
T -> F{MF}
F -> I|N|(E)
A -> +|-
M -> *|/
I -> (a|…|z|A|…|Z){a|…|z|A|…|Z|0|…|9}
N -> (1|…|9){0|…|9}
经过分析,非终结符A、M、I、N在采用递归下降分析程序中是无需单独写为函数的,可以和其他非终结符合并书写,因为他们可以理解为终结符来用。

三、算法流程

算法的流程图就是对各种单词符号的组合进行判断。
整个程序分为主程序和三个子程序,三个子程序即递归调用的函数。
在这里插入图片描述
在这里插入图片描述

四、源程序

语言:c++

#include <iostream>
#define plus 0      // +
#define minus 1     // -
#define times 2     // *
#define slash 3     // /
#define lparen 4    // (
#define rparen 5    // )
#define ident 6     // 标识符
#define number 7    // 无符号整数
#define finish 8    // 完成
#include <string>
#include <fstream>
using namespace std;

//ifstream symbol;//读文件使用
int sym;//当前的输入符号
bool error;//判断分析成功与否
void advance();//读入下一单词符号
void expression();//表达式--递归下降子程序
void term();//项--递归下降子程序
void factor();//因子--递归下降子程序

void advance()//读入下一单词符号
{
    //if(!symbol.eof())//从文件读取
    //{
    static int count=7;//需要设置一个读取结束标志,故以读取次数结束
    if(count>0)
    {
        count--;
        string temp;
        //getline(symbol,temp);//读取一行(读文件使用)
        cin>>temp;
        int word_begin=temp.find(',');//找到单词符号的结尾
        string keyword=temp.substr(1,word_begin-1);//将单词符号截取出来,去掉无用字符
        //cout<<temp<<endl;
        if(keyword=="plus")sym=plus;
        else if(keyword=="minus")sym=minus;
        else if(keyword=="times")sym=times;
        else if(keyword=="slash")sym=slash;
        else if(keyword=="lparen")sym=lparen;
        else if(keyword=="rparen")sym=rparen;
        else if(keyword=="ident")sym=ident;
        else if(keyword=="number")sym=number;
        else sym=finish;//单词错误,分析结束
    }
    else
	{
        //cout<<"分析结束!"<<endl;
        sym=finish;
    }
}

void expression()//表达式--递归下降子程序
{
    if((sym==plus)||(sym==minus))advance();//表达式前面的符号可有可无,有时需要读入下一符号
    term();
    while((sym==plus)||(sym==minus))//后面一段可以重复多次
    {
        advance();
        term();
    }
}

void term()//项--递归下降子程序
{
    factor();
    while((sym==times)||(sym==slash))//后面一段可以重复多次
    {
        advance();
        factor();
    }
}

void factor()//因子--递归下降子程序
{
    if(sym==ident)advance();//单词为标识符
    else if(sym==number)advance();//单词为无符号整数
    else if(sym==lparen)//单词为左括号
    {
        advance();
        expression();
        if(sym==rparen)advance();//右括号匹配
        else
        {
            error=false;//分析报错
            //cout<<"右括号不匹配"<<endl;
        }
    }else
    {
        error=false;//分析报错
        //cout<<"符号不属于因子!"<<endl;
    }
}

int main()
{
    error=true;//默认分析成功
    //symbol.open("result.txt");//打开文件,获取数据
    advance();
    expression();//表达式是起始分析点
    if(error)printf("Yes,it is correct.\n");
    else printf("No,it is wrong.\n");
    //symbol.close();
    return 0;
}
五、数据测试

注意输入也是有2种方式,记得在程序里修改。
输入输出示例:
在这里插入图片描述

  • 2
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
递归下降分析法 一、实验目的: 根据某一文法编制调试递归下降分析程序,以便对任意输入的符号串进行分析。本次实验的目的主要是加深对递归下降分析法的理解。 二、实验说明 1、递归下降分析法的功能 词法分析器的功能是利用函数之间的递归调用模拟语法树自上而下构造过程。 2、递归下降分析法的前提 改造文法:消除二义性、消除左递归、提取左因子,判断是否为LL(1)文法, 3、递归下降分析法实验设计思想及算法 为G的每个非终结符号U构造一个递归过程,不妨命名为U。 U的产生式的右边指出这个过程的代码结构: (1)若是终结符号,则和向前看符号对照, 若匹配则向前进一个符号;否则出错。 (2)若是非终结符号,则调用与此非终结符对应的过程。当A的右部有多个产生式时,可用选择结构实现。 三、实验要求 (一)准备: 1.阅读课本有关章节, 2.考虑好设计方案; 3.设计出模块结构、测试数据,初步编制好程序。 (二)上课上机: 将源代码拷贝到机上调试,发现错误,再修改完善。第二次上机调试通过。 (三)程序要求: 程序输入/输出示例: 对下列文法,用递归下降分析法对任意输入的符号串进行分析: (1)E->eBaA (2)A->a|bAcB (3)B->dEd|aC (4)C->e|dc 输出的格式如下: (1)递归下降分析程序,编制人:姓名,学号,班级 (2)输入一以#结束的符号串:在此位置输入符号串例如:eadeaa# (3)输出结果:eadeaa#为合法符号串 注意: 1.如果遇到错误的表达式,应输出错误提示信息(该信息越详细越好); 2.对学有余力的同学,可以详细的输出推导的过程,即详细列出每一步使用的产生式。 (四)程序思路 0.定义部分:定义常量、变量、数据结构。 1.初始化:从文件将输入符号串输入到字符缓冲区中。 2.利用递归下降分析分析,对每个非终结符编写函数,在主函数中调用文法开始符号的函数。
好的,我可以为您提供一些关于pl/0语言词法分析器C++实现的相关信息。 首先,pl/0是一种简单的过程化语言,常用于编译原理的教学中。它的语法比较简单,只有少数的语法元素,如变量声明、赋值语句、条件语句、循环语句等。 其次,词法分析器是编译器的一个组成部分,它的作用是将源代码中的字符序列转换为单词序列,也就是词法单元。在pl/0语言中,词法单元包括关键字、标识符、常数、运算符等。 下面是一个简单的pl/0语言词法分析器C++实现,供您参考: ```c++ #include <iostream> #include <string> #include <cctype> using namespace std; enum TokenType { KEYWORD, IDENTIFIER, NUMBER, OPERATOR, DELIMITER, ERROR }; struct Token { TokenType type; string value; }; string keywords[] = { "const", "var", "procedure", "begin", "end", "if", "then", "else", "while", "do", "call", "read", "write", "odd" }; string operators[] = { "+", "-", "*", "/", "=", "<>", "<", "<=", ">", ">=", ":=" }; string delimiters[] = { ",", ";", ".", "(", ")" }; bool isKeyword(string str) { for (int i = 0; i < 14; i++) { if (keywords[i] == str) { return true; } } return false; } bool isOperator(string str) { for (int i = 0; i < 11; i++) { if (operators[i] == str) { return true; } } return false; } bool isDelimiter(string str) { for (int i = 0; i < 5; i++) { if (delimiters[i] == str) { return true; } } return false; } Token lex(string input) { Token token; token.value = input; if (isKeyword(input)) { token.type = KEYWORD; } else if (isdigit(input[0])) { token.type = NUMBER; for (int i = 1; i < input.length(); i++) { if (!isdigit(input[i])) { token.type = ERROR; break; } } } else if (isOperator(input)) { token.type = OPERATOR; } else if (isDelimiter(input)) { token.type = DELIMITER; } else { token.type = IDENTIFIER; } return token; } int main() { string input; cout << "Enter a pl/0 language token: "; cin >> input; Token token = lex(input); cout << "Token value: " << token.value << endl; switch (token.type) { case KEYWORD: cout << "Token type: keyword" << endl; break; case IDENTIFIER: cout << "Token type: identifier" << endl; break; case NUMBER: cout << "Token type: number" << endl; break; case OPERATOR: cout << "Token type: operator" << endl; break; case DELIMITER: cout << "Token type: delimiter" << endl; break; case ERROR: cout << "Token type: error" << endl; break; } return 0; } ``` 该程序首先定义了一个枚举类型`TokenType`,用于标识词法单元的类型。然后定义了一个`Token`结构体,包含了词法单元的类型和值。 接着定义了三个字符串数组,分别存储关键字、运算符和分隔符。通过`isKeyword`、`isOperator`和`isDelimiter`函数判断输入字符串是否为关键字、运算符或分隔符。 最后定义了`lex`函数,用于将输入的字符串转换为`Token`结构体。该函数首先判断输入字符串的类型,然后返回一个`Token`结构体。 在`main`函数中,通过调用`lex`函数将输入字符串转换为一个`Token`结构体,并根据其类型输出相应的信息。 以上就是一个简单的pl/0语言词法分析器C++实现,希望能对您有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值