算符优先文法
需求描述
对于任意给定的文法,判断其是否是算符优先文法,如果是则构造出算符优先关系表。
算法描述
主要是先判断输入的数据是否是一个文法,然后通过判断是否存在连续两个相邻的非终结符来判断它是否是算符优先文法,若不是,则直接提示并退出程序;否则,依次求得所有非终结符的FIRSTVT集与LASTVT集,然后根据规则构造优先关系表,当任意两终结符之间不存在多种优先关系时,说明它是算符优先文法,否则不是。
FIRSTVT集与LASTVT集的构造
Firstvt
找Firstvt的三条规则:如果要找A的Firstvt,A的候选式中出现:
- A->a…,即以终结符开头,该终结符入Firstvt
- A->B…,即以非终结符开头,该非终结符的Firstvt入A的Firstvt
- A->Ba…,即先以非终结符开头,紧跟终结符,则终结符入Firstvt
Lastvt
找Lastvt的三条规则:如果要找A的Lastvt,A的候选式中出现:
- A->…a,即以终结符结尾,该终结符入Lastvt
- A->…B,即以非终结符结尾,该非终结符的Lastvt入A的Lastvt
- A->…aB,即先以非终结符结尾,前面是终结符,则终结符入Firstvt
代码实现
#include <iostream>
#include<cstdio>
#include <string>
#include <iomanip>
using namespace std;
//文法类
class Analysis{
public:
Analysis():one('\0'), two(""){}
char one;
string two;
};
//FIRSTVT集、LASTVT集、LL1分析表
Analysis firstvt[20], lastvt[20], form[10][10];
//规范字符集,其中$表示空符号,^表示箭头
const string spec_scs = "()^|$#+_*/";
string final_str; //终结符集
string gram[10]; //文法数组
int final_num = 0; //终结符个数
int firstvt_num = 0; //firstvt的元素个数
int lastvt_num = 0; //lastvt的元素个数
int gramer_size = 0; //文法行数
int id=0; //0表示是算符优先文法
bool input(); //输入函数
//通过检查数组gram的每个元素是否存在两个终结符相邻,进而判断是否是算符优先文法
bool isOperator_Priority_Grammar(const string gram[]);
bool ifnorm(char ch); //判断是否是输入规范字符
bool ifnfinal(char ch); //判断是否是非终结符,若是则返回true
bool iffinal(char ch); //判断是否是终结符,若是则返回true
//返回c在Analysis数组vt的前n个元素的one成员变量中第一出现的位置,用整数表示,查找失败返回-1
int findch(Analysis vt[],char c, int n);
//返回c在str中第一出现的位置,用整数表示,查找失败返回-1
int findch(string vt,char c);
void getFirstvt(); //firstvt的获取
void getLastvt(); //lastvt的获取
void setAnalysis_Table(); //建立分析表
void printFirstvt(); //打印FIRSTVT集
void printLastvt(); //打印LASTVT集
void printAnalysis_Table(); //打印分析表
int main(){
//输入文法
bool read = input();
if(!read)
{
cout << "含有非法输入字符" << endl;
return 0;
}
//判断算符优先文法
if (!isOperator_Priority_Grammar(gram))
{
cout << "该算法不是算符优先文法" << endl;
return 0;
}
cout << "文法中不含相邻终结符" << endl;
//获取FIRSTVT集
getFirstvt();
getLastvt();
printFirstvt();
printLastvt();
setAnalysis_Ta