编译原理 LL(1)语法分析器java版 完整源代码

合集下载

编译原理语法分析器(java完美运行版)

编译原理语法分析器(java完美运行版)

编译原理语法分析器(java完美运行版)第一篇:编译原理语法分析器 (java完美运行版)实验二语法分析器一、实验目的通过完成预测分析法的语法分析程序,了解预测分析法和递归子程序法的区别和联系。

使学生了解语法分析的功能,掌握语法分析程序设计的原理和构造方法,训练学生掌握开发应用程序的基本方法。

有利于提高学生的专业素质,为培养适应社会多方面需要的能力。

二、实验内容υ根据某一文法编制调试 LL(1)分析程序,以便对任意输入的符号串进行分析。

υ构造预测分析表,并利用分析表和一个栈来实现对上述程序设计语言的分析程序。

υ分析法的功能是利用LL(1)控制程序根据显示栈栈顶内容、向前看符号以及LL(1)分析表,对输入符号串自上而下的分析过程。

三、LL(1)分析法实验设计思想及算法υ模块结构:(1)定义部分:定义常量、变量、数据结构。

(2)初始化:设立LL(1)分析表、初始化变量空间(包括堆栈、结构体、数组、临时变量等);(3)控制部分:从键盘输入一个表达式符号串;(4)利用LL(1)分析算法进行表达式处理:根据LL(1)分析表对表达式符号串进行堆栈(或其他)操作,输出分析结果,如果遇到错误则显示错误信息。

四、实验要求1、编程时注意编程风格:空行的使用、注释的使用、缩进的使用等。

2、如果遇到错误的表达式,应输出错误提示信息。

3、对下列文法,用LL(1)分析法对任意输入的符号串进行分析:(1)E->TG(2)G->+TG|—TG(3)G->ε(4)T->FS(5)S->*FS|/FS(6)S->ε(7)F->(E)(8)F->i 输出的格式如下:五、实验源程序LL1.java import java.awt.*;import java.awt.event.*;import javax.swing.*;import javax.swing.table.DefaultTableModel;import java.sql.*;import java.util.Vector;public class LL1 extends JFrame implements ActionListener { /****/private static final long serialVersionUID = 1L;JTextField tf1;JTextField tf2;JLabel l;JButton b0;JPanel p1,p2,p3;JTextArea t1,t2,t3;JButton b1,b2,b3;JLabel l0,l1,l2,l3,l4;JTable table;Statement sta;Connection conn;ResultSet rs;DefaultTableModel dtm;String Vn[]=null;Vector P=null;int firstComplete[]=null;//存储已判断过first的数据char first[][]=null;//存储最后first结果int followComplete[]=null;//存储已判断过follow的数据char follow[][]=null;//存储最后follow结果char select[][]=null;//存储最后select结果int LL=0;//标记是否为LL(1)String vt_tou[]=null;//储存VtObject shuju[][]=null;//存储表达式数据char yn_null[]=null;//存储能否推出空LL1(){ setLocation(100,0);setSize(700,780);tf1=new JTextField(13);tf2=new JTextField(13);l=new JLabel(“>>”);l0=new JLabel(“输入字符串:”);l1=new JLabel(“输入的文法”);l2=new JLabel(“ ”);l3=new JLabel(“分析的结”);l4=new JLabel(“预测分析”);//p1=new JPanel();p2=new JPanel();p3=new JPanel();t1=new JTextArea(24,20);t2=new JTextArea(1,30);t3=new JTextArea(24,40);b0=new JButton(“确定(S为开始)”);b1=new JButton(“ 判断文法”);为:果:表:b2=new JButton(“输入”);b3=new JButton(“清空”);table=new JTable();JScrollPane jp1=new JScrollPane(t1);JScrollPane jp2=new JScrollPane(t2);JScrollPane jp3=new JScrollPane(t3);p2.add(tf1);p2.add(l);p2.add(tf2);p2.add(b0);p2.add(b1);p2.add(l0);p2.add(l2);p2.add(jp2);p2. add(b2);p2.add(b3);p2.add(l1);p2.add(l3);p2.add(jp1);p2.add(jp3);p3.add(l4);p3.add(newJScrollPane(table));add(p2,“Center”);add(p3,“South”);b0.addActionListener(this);b1.addActionListener(this);b2.ad dActionListener(this);b3.addActionListener(this);setDefaultClose Operation(JFrame.EXIT_ON_CLOSE);table.setPreferredScrollable ViewportSize(new Dimension(660,200));setVisible(true);} public void actionPerformed(ActionEvent e){ if(e.getSource()==b0){ String a=tf1.getText();String b=tf2.getText();t1.append(a+'→'+b+'n');}if(e.getSource()==b1){ t3.setText(“");int Vnnum=0,k;Vn=new String[100];P=new Vector();String s[]=t1.getText().split(”n“);for(int i=0;ireturn;}if(s[i].charAt(0)<='Z'&&s[i].charAt(0)>='A'&&s[i].charAt(1)=='→'){ for(k=0;k=Vnnum){ Vn[Vnnum]=s[i].substring(0, 1);//存入Vn数据 Vnnum++;} P.add(s[i]);} else { t3.setText(”文法输入有误,请重新输入“);return;} } yn_null=new char[100];first=new char[Vnnum][100];int flag=0;String firstVn[]=null;firstComplete=new int[Vnnum];for(int i=0;Vn[i]!=null;i++)//依次求FIRST** { flag=0;firstVn=new String[20];if((flag=add_First(first[i],Vn[i],firstVn,flag))==-1)return;firstComplete[i]=1;} t3.append(”first集:“+”n“);//显示FIRST**for(inti=0;Vn[i]!=null;i++){ t3.append(”first(“+Vn[i]+”)={ “);for(int j=0;first[i][j]!='';j++){ t3.append(first[i][j]+” , “);} t3.append(”}“+”n“);}follow=new char[Vnnum][100];String followVn[]=null;followComplete=new int[Vnnum];for(int i=0;Vn[i]!=null;i++)//求FOLLOW** { flag=0;followVn=new String[20];if((flag=tianjiaFollow(follow[i],Vn[i],followVn,flag))==-1)return;followComplete[i]=1;} t3.append(”fol low集:“+”n“);//显示FOLLOW**for(inti=0;Vn[i]!=null;i++){ t3.append(”follow(“+Vn[i]+”)={ “);for(i nt j=0;follow[i][j]!='';j++){ t3.append(follow[i][j]+” , “);} t3.append(”}“+”n“);} select=new char[P.size()][100];for(int i=0;itianjiaSelect(select[i],(String)P.elementAt(i),flag);}t3.append(”select集:“+”n“);//显示SELECT**for(int i=0;ifor(int i=0;Vn[i]!=null;i++)//判断select交集是否为空{ intbiaozhi=0;char save[]=new char[100];for(int j=0;jif(t.substring(0,1).equals(Vn[i])){ for(k=0;select[j][k]!='';k++){ if(puanduanChar(save,select[j][k])){ save[biaozhi]=select[j][k];bia ozhi++;} else//当有交集时,不为LL(1)文法{ t3.append(”不是LL(1)文法!“+”n“);return;} } } } } char Vt[]=new char[100];int biaozhi=0;for(int i=0;i{ if(t.charAt(j)>'Z'||t.charAt(j)<'A'){ if(puanduanChar(Vt,t.cha rAt(j))){ Vt[biaozhi]=t.charAt(j);biaozhi++;} } } } if(puanduanChar(Vt,'#'))//若可推出空集,则将#加入Vt。

编译原理词法分析器-ll1-lr0-python实现代码

编译原理词法分析器-ll1-lr0-python实现代码

编译原理词法分析器-ll1-lr0-python实现代码计算机科学与通信工程学院编译原理实验报告题目: 1.词法分析器2. LL(1)分析器3. LR(0)分析器班级:姓名:学号:指导老师:2017年月目录一、实验题目 (1)二、实验目的和要求 (1)三、代码实现 (2)四、总结 (25)一、实验题目1.词法分析器分析一段程序代码,将代码中的单词符号分解出来,并对其进行检查,输出token表和error表2.LL(1)文法分析器分析给定文法。

求出文法的FIRST集,FOLLOW集,并构建分析表,对给定输入串进行分析。

3.LR(0)文法分析器分析给定文法。

用Ꜫ_CLOSURE方法构造文法的LR(0)项目集规范族,根据状态转换函数GO构造出文法的DFA,并转换为分析表,对给定输入串进行分析。

二、实验目的和要求1.学会词法分析器的实现思路。

2.学会求解FIRST集, FOLLOW集,构造LL(1)分析表。

3.学会Ꜫ_CLOSURE方法,状态转换函数GO, 构造LR(0)分析表。

三、代码实现1.词法分析器program.txt 中存放要分析的文法:E->TRR->+TR|-TR|~T->FGG->*FG|/FG|~F->(E)|i代码:KEYWORD_LIST = ['while', 'if', 'else', 'switch', 'case']SEPARATOR_LIST = [';', ':', ',', '(', ')', '[', ']', '{', '}']OPERATOR_LIST1 = ['+', '-', '*']OPERATOR_LIST2 = ['<=', '<', '==', '=', '>', '>=']CATEGORY_DICT = {# KEYWORD"while": {"while": ""},"if": {"if": ""},"else": {"else": ""},"switch": {"switch": ""},"case": {"case": ""},# OPERATOR"+": {"+": ""},"-": {"-": ""},"*": {"*": ""},"<=": {"relop": "LE"},"<": {"relop": "LT"},">=": {"relop": "GE"},">": {"relop": "GT"},"==": {"relop": "EQ"},"=": {"=": ""},# SEPARATOR";": {";": ""},":": {":": ""},",": {",": ""},"(": {"(": ""},")": {")": ""},"[": {"]": ""},"]": {"]": ""},"{": {"{": ""},"}": {"}": ""},}CONSTANTTABLE = []TOKENTABLE = []OPERATORTABLE = []KEYWORDTABLE = []SEPARATORTABLE = []UNDEFINEDTABLE = []# READ FILEdef read_file(path, method):temp_str = ""try:file = open(path, method)for line in file:line = line.replace('\n', " ") temp_str += linetemp_str = str(temp_str)except IOError as e:print(e)exit()finally:file.close()return temp_str.strip() + " "# GETBEdef getbe():global tokengetchar()token = ""return# GETCHARdef getchar():global characterglobal locationwhile all_string[location] == " ":location = location + 1character = all_string[location]return character# LINK TOKENdef concatenation():global tokenglobal charactertoken = token + character# IS NUMBERdef digit():if '0' <= character <= '9':return Truereturn False# IS ALPHABETdef letter():if 'A' <= character <= 'Z' or 'a' <= character <= 'z': return Truereturn False# IS IDENTIFIERdef reserve():if token in KEYWORD_LIST:return CATEGORY_DICT[token]else:return 0# RETRACTdef retract():global locationglobal character# location = location - 1character = ""return# MAIN FUNCTIONdef main():global tokenglobal characters = getchar()getbe()if 'a' <= s <= 'z' or 'A' <= s <= 'Z':while letter() or digit():concatenation()location = location + 1character = all_string[location]retract()c = reserve()if c == 0:TOKENTABLE.append(token)print("这是标识符:{'", token, "':'", TOKENTABLE.index(token), "'}") else:KEYWORDTABLE.append(token)print("这是保留字:", CATEGORY_DICT[token])elif '0' <= s <= '9':while digit():concatenation()location = location + 1character = all_string[location]retract()CONSTANTTABLE.append(token)print("这是常数:{'", token, "':'", CONSTANTTABLE.index(token), "'}") elif s in OPERATOR_LIST1:location = location + 1OPERATORTABLE.append(s)print("这是单操作符:", CATEGORY_DICT[s])elif s in OPERATOR_LIST2:location = location + 1character = all_string[location]if character == '=':OPERATORTABLE.append(s + character)print("这是双操作符:", CATEGORY_DICT[s + character])else:retract()location = location + 1OPERATORTABLE.append(s)print("这是单操作符:", CATEGORY_DICT[s])elif s in SEPARATOR_LIST:location = location + 1SEPARATORTABLE.append(s)print("这是分隔符:", CATEGORY_DICT[s])else:UNDEFINEDTABLE.append(s)print("error:undefined identity :'", s, "'")if __name__ == '__main__':character = ""token = ""all_string = read_file("program.txt", "r")location = 0while location + 1 < len(all_string):main()print('KEYWORDTABLE:', KEYWORDTABLE)print('TOKENTABLE:', TOKENTABLE)print('CONSTANTTABLE:', CONSTANTTABLE)print('OPERATORTABLE:', OPERATORTABLE)print('SEPARATORTABLE:', SEPARATORTABLE)运行结果:2.LL(1)分析器program.txt 中存放要分析的文法:E->TRR->+TR|-TR|~T->FGG->*FG|/FG|~F->(E)|i输入串:i+i*i代码:NonTermSet = set() # 非终结符集合TermSet = set() # 终结符集合First = {} # First集Follow = {} # Follow集GramaDict = {} # 处理过的产生式Code = [] # 读入的产生式AnalysisList = {} # 分析表StartSym = "" # 开始符号EndSym = '#' # 结束符号为“#“Epsilon = "~" # 由于没有epsilon符号用“~”代替# 构造First集def getFirst():global NonTermSet, TermSet, First, Follow, FirstAfor X in NonTermSet:First[X] = set() # 初始化非终结符First集为空for X in TermSet:First[X] = set(X) # 初始化终结符First集为自己Change = Truewhile Change: # 当First集没有更新则算法结束Change = Falsefor X in NonTermSet:for Y in GramaDict[X]:k = 0Continue = Truewhile Continue and k < len(Y):if not First[Y[k]] - set(Epsilon) <= First[X]: # 没有一样的就添加,并且改变标志if Epsilon not in First[Y[k]] and Y[k] in NonTermSet and k > 0: # Y1到Yi候选式都有~存在Continue = Falseelse:First[X] |= First[Y[k]] - set(Epsilon)Change = Trueif Epsilon not in First[Y[k]]:Continue = Falsek += 1if Continue: # X->~或者Y1到Yk均有~产生式First[X] |= set(Epsilon)# FirstA[Y] |= set(Epsilon)# 构造Follow集def getFollow():global NonTermSet, TermSet, First, Follow, StartSymfor A in NonTermSet:Follow[A] = set()Follow[StartSym].add(EndSym) # 将结束符号加入Follow[开始符号]中Change = Truewhile Change: # 当Follow集没有更新算法结束Change = Falsefor X in NonTermSet:for Y in GramaDict[X]:for i in range(len(Y)):if Y[i] in TermSet:continueFlag = Truefor j in range(i + 1, len(Y)): # continueif not First[Y[j]] - set(Epsilon) <= Follow[Y[i]]:Follow[Y[i]] |= First[Y[j]] - set(Epsilon) # 步骤2 FIRST(β)/~ 加入到FOLLOW(B)中。

编译原理实验报告《ll(1)语法分析器构造》

编译原理实验报告《ll(1)语法分析器构造》

规则右部首符号是终结

.
.
{ first[r].append(1,a); break;// 添加并结束
}
if(U.find(P[i][j])!=string::npos)// 规则右部首符号是非终结符 ,形如 X:: =Y1Y2...Yk
{
s=U.find(P[i][ j]);
//cout<<P[i][ j]<<":\n";
arfa=beta=""; for( j=0;j<100&&P[j][0]!=' ';j++) {
if(P[ j][0]==U[i]) {
if(P[ j][4]==U[i])// 产生式 j 有左递归 {
flagg=1;
.
.
for(temp=5;P[j][temp]!=' ';temp++) arfa.append(1,P[
{
int i,j,r,s,tmp;
string* first=new string[n];
char a;
int step=100;// 最大推导步数
while(step--){
// cout<<"step"<<100-step<<endl;
for(i=0;i<k;i++)
{
//cout<<P[i]<<endl;
j][temp]);
if(P[ j+1][4]==U[i]) arfa.append("|");//

编译原理实验二LL(1)语法分析实验报告

编译原理实验二LL(1)语法分析实验报告

专题3_LL(1)语法分析设计原理与实现李若森 13281132 计科1301一、理论传授语法分析的设计方法和实现原理;LL(1) 分析表的构造;LL(1)分析过程;LL(1)分析器的构造。

二、目标任务实验项目实现LL(1)分析中控制程序(表驱动程序);完成以下描述算术表达式的 LL(1)文法的LL(1)分析程序。

G[E]:E→TE’E’→ATE’|εT→FT’T’→MFT’|εF→(E)|iA→+|-M→*|/设计说明终结符号i为用户定义的简单变量,即标识符的定义。

加减乘除即运算符。

设计要求(1)输入串应是词法分析的输出二元式序列,即某算术表达式“专题 1”的输出结果,输出为输入串是否为该文法定义的算术表达式的判断结果;(2)LL(1)分析程序应能发现输入串出错;(3)设计两个测试用例(尽可能完备,正确和出错),并给出测试结果。

任务分析重点解决LL(1)表的构造和LL(1)分析器的实现。

三、实现过程实现LL(1)分析器a)将#号放在输入串S的尾部b)S中字符顺序入栈c)反复执行c),任何时候按栈顶Xm和输入ai依据分析表,执行下述三个动作之一。

构造LL(1)分析表构造LL(1)分析表需要得到文法G[E]的FIRST集和FOLLOW集。

构造FIRST(α)构造FOLLOW(A)构造LL(1)分析表算法根据上述算法可得G[E]的LL(1)分析表,如表3-1所示:表3-1 LL(1)分析表主要数据结构pair<int, string>:用pair<int, string>来存储单个二元组。

该对照表由专题1定义。

map<string, int>:存储离散化后的终结符和非终结符。

vector<string>[][]:存储LL(1)分析表函数定义init:void init();功能:初始化LL(1)分析表,关键字及识别码对照表,离散化(非)终结符传入参数:(无)传出参数:(无)返回值:(无)Parse:bool Parse( const vector<PIS> &vec, int &ncol );功能:进行该行的语法分析传入参数:vec:该行二元式序列传出参数:emsg:出错信息epos:出错标识符首字符所在位置返回值:是否成功解析。

编译原理LL(1)文法分析器实验(java)

编译原理LL(1)文法分析器实验(java)

编译原理LL(1)文法分析器实验本程序是基于已构建好的某一个语法的预测分析表来对用户的输入字符串进行分析,判断输入的字符串是否属于该文法的句子。

基本实现思想:接收用户输入的字符串(字符串以“#”表示结束)后,对用做分析栈的一维数组和存放分析表的二维数组进行初始化。

然后取出分析栈的栈顶字符,判断是否为终结符,若为终结符则判断是否为“#”且与当前输入符号一样,若是则语法分析结束,输入的字符串为文法的一个句子,否则出错若不为“#”且与当前输入符号一样则将栈顶符号出栈,当前输入符号从输入字符串中除去,进入下一个字符的分析。

若不为“#”且不与当前输入符号一样,则出错。

若栈顶符号为非终结符时,查看预测分析表,看栈顶符号和当前输入符号是否构成产生式,若产生式的右部为ε,则将栈顶符号出栈,取出栈顶符号进入下一个字符的分析。

若不为ε,将产生式的右部逆序的入栈,取出栈顶符号进入下一步分析。

程序流程图:本程序中使用以下文法作对用户输入的字符串进行分析:E→TE’E’→+TE’|εT→FT’T’→*FT’|εF→i|(E)该文法的预测分析表为:1、显示预测分析表,提示用户输入字符串2、输入的字符串为正确的句子:3、输入的字符串中包含了不属于终结符集的字符4、输入的字符串不是该文法能推导出来的句子程序代码:package ;import java.io.*;public class LL {String Vn[] = { "E", "E'", "T", "T'", "F" }; // 非终结符集String Vt[] = { "i", "+", "*", "(", ")", "#" }; // 终结符集String P[][] = new String[5][6]; // 预测分析表String fenxi[] ; // 分析栈int count = 1; // 步骤int count1 = 1;//’分析栈指针int count2 = 0, count3 = 0;//预测分析表指针String inputString = ""; // 输入的字符串boolean flag;public void setCount(int count, int count1, int count2, int count3){this.count = count;this.count1 = count1;this.count2 = count2;this.count3 = count3;flag = false;}public void setFenxi() { // 初始化分析栈fenxi = new String[20];fenxi[0] = "#";fenxi[1] = "E";}public void setP() { // 初始化预测分析表for (int i = 0; i < 5; i++) {for (int j = 0; j < 6; j++) {P[i][j] = "error";}}P[0][0] = "->TE'";P[0][3] = "->TE'";P[1][1] = "->+TE'";P[1][4] = "->ε";P[1][5] = "->ε";P[2][0] = "->FT'";P[2][3] = "->FT'";P[3][1] = "->ε";P[3][2] = "->*FT'";P[3][4] = "->ε";P[3][5] = "->ε";P[4][0] = "->i";P[4][3] = "->(E)";// 打印出预测分析表System.out.println(" 已构建好的预测分析表");System.out.println("----------------------------------------------------------------------");for (int i=0; i<6; i++) {System.out.print(" "+Vt[i]);}System.out.println();System.out.println("----------------------------------------------------------------------");for (int i=0; i<5; i++) {System.out.print(" "+Vn[i]+" ");for (int j=0; j<6; j++) {int l = 0;if (j>0) {l = 10-P[i][j-1].length();}for (int k=0; k<l; k++) {System.out.print(" ");}System.out.print(P[i][j]+" ");}System.out.println();}System.out.println("----------------------------------------------------------------------"); }public void setInputString(String input) {inputString = input;}public boolean judge() {String inputChar = inputString.substring(0, 1); // 当前输入字符boolean flage = false;if (count1 >= 0) {for (int i=0; i<6; i++) {if (fenxi[count1].equals(Vt[i])) { // 判断分析栈栈顶的字符是否为终结符flage = true;break;}}}if (flage) {// 为终结符时if (fenxi[count1].equals(inputChar)) {if (fenxi[count1].equals("#")&&inputString.length()==1) { // 栈顶符号为结束标志时// System.out.println("最后一个");String fenxizhan = "";for (int i=0; i<=P.length; i++) { // 拿到分析栈里的全部内容(滤去null)if (fenxi[i] == null) {break;} else {fenxizhan = fenxizhan + fenxi[i];}}// 输出当前分析栈情况,输入字符串,所用产生式或匹配System.out.print(" " + count);String countToString = Integer.toString(count);int farWay = 14 - countToString.length();for (int k=0; k<farWay; k++) {System.out.print(" ");}System.out.print(fenxizhan);farWay = 20 - fenxizhan.length();for (int k=0; k<farWay; k++) {System.out.print(" ");}System.out.print(inputString);farWay = 25 - inputString.length();for (int k=0; k<farWay; k++) {System.out.print(" ");}System.out.println("接受");flag = true;return true;} else {// 分析栈栈顶符号不为结束标志符号时String fenxizhan = "";for (int i=0; i<=P.length; i++) { // 拿到分析栈里的全部内容(滤去null)if (fenxi[i] == null) {break;} else {fenxizhan = fenxizhan + fenxi[i];}}// 输出当前分析栈情况,输入字符串,所用产生式或匹配System.out.print(" "+count);String countToString = Integer.toString(count);int farWay = 14 - countToString.length();for (int k=0; k<farWay; k++) {System.out.print(" ");}System.out.print(fenxizhan);farWay = 20 - fenxizhan.length();for (int k=0; k<farWay; k++) {System.out.print(" ");}System.out.print(inputString);farWay = 25 - inputString.length();for (int k=0; k<farWay; k++) {System.out.print(" ");}System.out.println("\"" + inputChar + "\"" + "匹配");// 将栈顶符号出栈,栈顶指针减一fenxi[count1] = null;count1 -= 1;if (inputString.length() > 1) { // 当当前输入字符串的长度大于1时,将当前输入字符从输入字符串中除去inputString = inputString.substring(1, inputString.length());} else { // 当前输入串长度为1时inputChar = inputString;}// System.out.println(" "+count+" "+fenxizhan+"// "+inputString +" "+P[count3][count2]);// System.out.println(count + inputChar + "匹配");count++;judge();}}else { // 判断与与输入符号是否一样为结束标志System.out.println(" 分析到第" + count + "步时出错!");flag = false;return false;}} else {// 非终结符时boolean fla = false;for (int i=0; i<6; i++) { // 查询当前输入符号位于终结符集的位置if (inputChar.equals(Vt[i])) {fla = true;count2 = i;break;}}if(!fla){System.out.println(" 分析到第" + count + "步时出错!");flag = false;return false;}for (int i=0; i<5; i++) { // 查询栈顶的符号位于非终结符集的位置if (fenxi[count1].equals(Vn[i])) {count3 = i;break;}}if (P[count3][count2] != "error") { // 栈顶的非终结符与输入的终结符存在产生式时String p = P[count3][count2];String s1 = p.substring(2, p.length()); // 获取对应的产生式if (s1.equals("ε")) { // 产生式推出“ε”时String fenxizhan = "";for (int i=0; i<=P.length; i++) {if (fenxi[i] == null) {break;} else {fenxizhan = fenxizhan + fenxi[i];}}// 输出当前分析栈情况,输入字符串,所用产生式或匹配System.out.print(" " + count);String countToString = Integer.toString(count);int farWay = 14 - countToString.length();for (int k=0; k<farWay; k++) {System.out.print(" ");}System.out.print(fenxizhan);farWay = 20 - fenxizhan.length();for (int k=0; k<farWay; k++) {System.out.print(" ");}System.out.print(inputString);farWay = 25 - inputString.length();for (int k=0; k<farWay; k++) {System.out.print(" ");}System.out.println(fenxi[count1] + P[count3][count2]);// 将栈顶符号出栈,栈顶指针指向下一个元素fenxi[count1] = null;count1 -= 1;count++;judge();} else { // 产生式不推出“ε”时int k = s1.length();String fenxizhan = "";for (int i=0; i<=P.length; i++) {if (fenxi[i] == null) {break;} else {fenxizhan = fenxizhan + fenxi[i];}}// 输出当前分析栈情况,输入字符串,所用产生式或匹配System.out.print(" "+count);String countToString = Integer.toString(count);int farWay = 14 - countToString.length();for (int o=0; o<farWay; o++) {System.out.print(" ");}System.out.print(fenxizhan);farWay = 20 - fenxizhan.length();for (int o=0; o<farWay; o++) {System.out.print(" ");}System.out.print(inputString);farWay = 25 - inputString.length();for (int o=0; o<farWay; o++) {System.out.print(" ");}System.out.println(fenxi[count1] + P[count3][count2]);for (int i=1; i<=k; i++) { // 将产生式右部的各个符号入栈String s2 = s1.substring(s1.length() - 1, s1.length());s1 = s1.substring(0, s1.length() - 1);if (s2.equals("'")) {s2 = s1.substring(s1.length() - 1, s1.length())+ s2;i++;s1 = s1.substring(0, s1.length() - 1);}fenxi[count1] = s2;if (i < k)count1++;// System.out.println("count1=" + count1);}// System.out.println(" "+count+" "+fenxizhan+"// "+inputString +" "+P[count3][count2]);count++;// System.out.println(count);judge();}} else {System.out.println(" 分析到第" + count + "步时出错!");flag = false;return false;}}return flag;}public static void main(String args[]) {LL l = new LL();l.setP();String input = "";boolean flag = true;while (flag) {try {InputStreamReader isr = new InputStreamReader(System.in);BufferedReader br = new BufferedReader(isr);System.out.println();System.out.print("请输入字符串(输入exit退出):");input = br.readLine();} catch (Exception e) {e.printStackTrace();}if(input.equals("exit")){flag = false;}else{l.setInputString(input);l.setCount(1, 1, 0, 0);l.setFenxi();System.out.println();System.out.println("分析过程");System.out.println("----------------------------------------------------------------------");System.out.println(" 步骤| 分析栈| 剩余输入串| 所用产生式");System.out.println("----------------------------------------------------------------------");boolean b = l.judge();System.out.println("----------------------------------------------------------------------");if(b){System.out.println("您输入的字符串"+input+"是该文发的一个句子");}else{System.out.println("您输入的字符串"+input+"有词法错误!");}}}}}。

北邮编译原理LL(1)语法分析程序

北邮编译原理LL(1)语法分析程序

{
printf("\n 分析结果:%s\n\n",Analyse(source));
}
while(1);
return 0;
}
将其改写 LL(1)文法:
手动生成的 FOLLOW 集合为: 生成的预测分析表为:
输入表达式:(通过文件输入)
对表达式((a+b)*3/5)#首先转换为 token 序列,以 i 代表标识符,以 n 代表常 量,然后进行预测分析:
如果匹配成功则接受,如果匹配不成功则返回错误信息。
给定文法的产生式:
E->E+T | E-T | T
T->T*F | T/F | F
F-> id | (E) | num
源代码:
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <stack> using namespace std; struct Node1 {
{
l=strlen(FOLLO)
{
MAP[k].vn=G[i][0];
MAP[k].vt=FOLLOW[i][j];
strcpy(MAP[k].s,Right[i]);
k++;
}
}
printf("\n 表达式文法的预测分析表如下:\n\n");
printf("
printf(" %s\n",G[i]);
printf("_______________________________________________________________ _________________\n");

编译原理课程设计LR1分析语法分析器实现(C++)

编译原理课程设计LR1分析语法分析器实现(C++)

编译原理课程设计LR1分析语法分析器实现(C++)输⼊的⽂法(第⼀⾏是终结符)将⽂法保存在txt中,命名为text.txt,与LR1.cpp放在同⼀⽬录中即可运⾏。

text.txtabcdeS->aAdS->bAcS->aecS->bedA->e实现代码:LR1.cpp1 #include<fstream>2 #include<iostream>3 #include<string>4 #include<vector>5 #include <algorithm>6#define MAX_Count 1007 #include <set>8 #include <stack>9 #include <iomanip>10 #include <sstream>11 #include <string>12 #include<cstring>13 #include <map>14using namespace std;151617// 重载⼀下+号运算符18 template <typename CSS_LR1>19 vector<CSS_LR1> &operator +(vector<CSS_LR1> &v1,vector<CSS_LR1> &v2)20 {21 v1.insert(v1.end(),v2.begin(),v2.end());22return v1;23 }242526struct VN_Set{27string VN_name;//⾮终结符28set<string> FIRST; //First集合29set<string> FOLLOW;30 };31struct CSS{32string start;//⾮终结符33 vector<string> next; //First集合34 };35struct CSS_LR1{36string start;//⾮终结符37 vector<string> next; //First集合38int num;39 vector<string> tail;40//41// bool operator==(CSS_LR1& rhs) const {42// return (start == rhs.start &&43// next == rhs.next &&44// num == rhs.num &&45// tail == rhs.tail);46// }47bool operator==(const CSS_LR1& rhs) {48return (start == rhs.start &&49 next == rhs.next &&50 num == rhs.num &&51 tail == rhs.tail);52 }5354 };5556int CSSCount = 0;57 CSS css[MAX_Count];//产⽣式58 VN_Set VN_First[MAX_Count];//⾮终结符集的First集合59set<string> VN;// ⾮终结符集合60set<string> VT;//终结符集合61int I_count = 0;//记录LR1项⽬数62 vector<CSS_LR1> I[MAX_Count]; //项⽬集63 map<string,int> mark_Follow;//⽤于标记Follow 防⽌套娃64 map<string,int> GOTO[MAX_Count];65 map<string,string> ACTION[MAX_Count];666768bool cmp_vector(vector<CSS_LR1>&v1, vector<CSS_LR1>&v2)69 {70if(v1.size()!=v2.size()) return false;71for (int i=0; i<v2.size(); i++)72 {73 CSS_LR1 t;74 t = v2[i];75 vector<CSS_LR1>::iterator result = find(v1.begin( ), v1.end( ),t); //查找376if (result == v1.end( )) //没找到77return false;78 }79return true;80 }8182/*83*实现编译原理语法分析中计算⾮终结符的First集Follow集84*/85set<string> get_FIRST(string a){ //求First集合86set<string> T;87for(int i = 0;i<CSSCount;i++){88if(css[i].start==a){ // a->..89for(int j=0;j<css[i].next.size();j++){90if(VT.find(css[i].next[j])!=VT.end()){ //是终结符开头91 T.insert(css[i].next[j]);92// T.erase("*");93break;94 }95else{96if(css[i].next[j]==css[i].start){102if(j!=css[i].next.size()-1)103 T.erase("$");104 }else{105106break;107 }108 }109110111 }112113 }114 }115116return T;117 }118119set<string> get_FOLLOW(string a){120set<string> T;121//cout<<"现在在求"<<a<<" 的Follow"<<endl;122 mark_Follow[a]++;123if(mark_Follow[a]>=2){124return T;125 }126127set<string> temp;128if(a==css[0].start){129 T.insert("#");130 }131for(int i = 0;i<CSSCount;i++){132for(int j =0;j<css[i].next.size();j++){133if(VT.find(css[i].next[j])==VT.end()&&a==css[i].next[j]){ //是⾮终结符,求FOLLOW集合134if(j==css[i].next.size()-1&&a!=css[i].start){//S->...a135set<string> tt = get_FOLLOW(css[i].start);136 T.insert(tt.begin(),tt.end());137 }138for(int k=j+1;k<css[i].next.size();k++){139if(VT.find(css[i].next[k])!=VT.end()){//后⾯⼀个是终结符 S->..av..140 T.insert(css[i].next[k]);141break;142 }143else{144 temp = get_FIRST(css[i].next[k]);145if(temp.find("$")!=temp.end()){//有$ S->..a B..146 T.insert(temp.begin(),temp.end());147 T.erase("$");148if(k==css[i].next.size()-1){ //S->..a B149set<string> tt = get_FOLLOW(css[i].start);150 T.insert(tt.begin(),tt.end());151break;152 }153 }else{154 T.insert(temp.begin(),temp.end());155break;156 }157 }158 }159160 }161 }162163 }164//cout<<a<<" "<<mark_Follow[a]<<endl;165 mark_Follow[a]=0;166return T;167 }168169170void GetFirst_and_Follow(){171set<string>::iterator it;172int count = 0;173 cout<<"========================================="<<endl;174 cout<<'\t' <<"FIRST集合"<<""<<"FOLLOW集合"<<endl;175for(it=VN.begin ();it!=VN.end ();it++)176 {177178 VN_First[count].VN_name = *it;179 VN_First[count].FIRST = get_FIRST(*it);180181 mark_Follow[*it]=0;182 VN_First[count].FOLLOW = get_FOLLOW(*it);183184//-----------输出FIRST--------------------185186 cout<<VN_First[count].VN_name<<'\t';187set<string>::iterator it;188for(it=VN_First[count].FIRST.begin();it!=VN_First[count].FIRST.end();it++){189 cout<<*it<<"";190 }191 cout<<'\t'<<"";192//----------------------------------------193194195196197//------------输出FOLLOW--------------198set<string>::iterator it1;199for(it1=VN_First[count].FOLLOW.begin();it1!=VN_First[count].FOLLOW.end();it1++){200 cout<<*it1<<"";201 }cout<<endl;202203//----------------------204205 count++;206 }cout<<"=========================================";207 cout<<endl<<endl;208 }209210211212213214void input(){215//创建⼀个⽂件输⼊流对象216 ifstream inFile;217//打开⽂件218 inFile.open("test.txt");223 cout << "file doesn't exist" << endl;224225string temp;226 getline(inFile,temp);227for(int j=0;j<temp.length();j++){228 VT.insert(temp.substr(j,1));229 }230set<string>::iterator p;231 cout<<"终结符号:";232for(p = VT.begin();p!=VT.end();p++){233 cout<<*p<<",";234 }cout<<endl;235236int count = 0;//⽂件⾏数237while(getline(inFile,temp)) //按⾏读取⽂件内容238 {239 css[count].start = temp[0] ;240for(int j=3;j<temp.length();j++){241 css[count].next.push_back(temp.substr(j,1));242 }243 VN.insert(css[count].start);//⾮终结符244245 cout<<css[count].start<<"->";246 vector<string>::iterator it;247for(it=css[count].next.begin();it!=css[count].next.end();it++){248 cout<<*it;249 }250 cout<<endl;251252253 count++;254 }255 CSSCount = count;256257258 }259260bool find_in_vector(vector<CSS_LR1> T,CSS_LR1 p){261 vector<CSS_LR1>::iterator it;262for(it=T.begin();it!=T.end();it++){263if(*it==p){264return true;265 }266 }267return false;268 }269270271 vector<CSS_LR1> CLOSURE(CSS_LR1 I){//求闭包272 vector<CSS_LR1> T;273//T.push_back(I);274if(I.num>=I.next.size()) { //规约项⽬A->α.或者接受项⽬275return T;276 }277else{278string temp = I.next[I.num];279if(VT.find(temp)!=VT.end()){ //点后⾯的是终结符 ,移进项⽬ A→α.aβ280return T;281 }282else{ //待约项⽬283for(int i = 0;i<CSSCount;i++){284if(css[i].start==temp){285 CSS_LR1 p;286 p.start = css[i].start;287 p.num = 0;//点在最前⾯288 p.next = css[i].next;289290set<string> f1;291for(int j = I.num+1;j<I.next.size();j++){292set<string> f2;//⽤于暂存first293294if(VT.find(I.next[j])!=VT.end()){295296 f2.insert(I.next[j]);297 }else{298 f2 = get_FIRST(I.next[j]);299 }300301 f1.insert(f2.begin(),f2.end());302if(f2.find("$")==f2.end()){303304break;305 }306 }307308if(f1.size()==0){309 p.tail=I.tail;310 }311else{312 vector<string> first_tail;313if(f1.find("$")!=f1.end()){314 f1.erase("$");315 copy(f1.begin(),f1.end(), back_inserter(first_tail));316 first_tail.insert(first_tail.end(),I.tail.begin(),I.tail.end()); 317 }else{318 copy(f1.begin(),f1.end(), back_inserter(first_tail));319//cout<<first_tail[0]<<endl;320 }321// vector<string>::iterator l;322// for(l=first_tail.begin();l!=first_tail.end();l++){323// cout<<*l<<" ";324// }cout<<endl;325 p.tail=first_tail;326 }327if(!find_in_vector(T,p)){328329 T.push_back(p);330 vector<CSS_LR1> ol = CLOSURE(p);331 vector<CSS_LR1>::iterator z;332for(z=ol.begin();z!=ol.end();z++){333if(find_in_vector(T,*z)){334 }else{335 T.push_back(*z);336 }337 }338339 }344 }345346return T;347 }348349void showI(vector<CSS_LR1> I){//展⽰项⽬集350 vector<CSS_LR1>::iterator it;351for(it=I.begin();it!=I.end();it++){352 CSS_LR1 p = *it;353 cout<<p.start<<"->";354 vector<string>::iterator s;355for(int j = 0;j<p.next.size();j++){356if(j==p.num) cout<<".";357 cout<<p.next[j];358 }if(p.num==p.next.size())cout<<".";359 cout<<",";360for(int k = 0;k<p.tail.size();k++){361 cout<<p.tail[k];362 }cout<<endl;363 }364 }365366void LR1_Analyse(){367 CSS_LR1 p;368//初始项⽬ S’->.S ,#369 p.start = css[0].start+"^";370 p.num = 0;//点在最前⾯371 p.tail.push_back("#");372 p.next.push_back(css[0].start);373374 I[0] = CLOSURE(p);//求闭包后的I[0]375 I[0].insert(I[0].begin(),p);///////////////求闭包遇到了⼀些问题376 I_count=1;377378//计算项⽬集379for(int i=0;i<I_count;i++){//每个项⽬集项⽬集I(i)380381 cout<<"==================="<<endl;382 cout<<"现在在计算项⽬集I"<<i<<endl;383 showI(I[i]);//展⽰项⽬集384 cout<<"==================="<<endl;385386//---------求ACTION的r部分--------------387 vector<CSS_LR1>::iterator t;388for(t=I[i].begin();t!=I[i].end();t++){389 CSS_LR1 t2 = *t;390if(t2.num==t2.next.size()){391int num =0;392for(int xp=0;xp<CSSCount;xp++){393if(css[xp].start==t2.start&&css[xp].next==t2.next){394 num = xp;395break;396 }397 }398399 std::stringstream ss;400 ss<<num;401string s = ss.str();402for(int q = 0;q<t2.tail.size();q++){403 ACTION[i][t2.tail[q]] = "r"+s;404 }405if(t2.num==1&&t2.next[0]==css[0].start){406 ACTION[i]["#"] = "acc";407 }408 }409 }410//--------------------------------------411412413414set<string>::iterator it;415for(it=VN.begin();it!=VN.end();it++){ //每个⾮终结符416//cout<<"项⽬集I"<<i<<"输⼊"<<*it<<endl;417 vector<CSS_LR1> temp;418//cout<<"项⽬集⼤⼩"<<I[i].size()<<endl;419for(int j = 0;j<I[i].size();j++){420 CSS_LR1 lr = I[i][j];421if(lr.num<lr.next.size()&&lr.next[lr.num]==*it){422//cout<<*it<<endl;423 vector<CSS_LR1> t2;424 lr.num++;425 t2 = CLOSURE(lr);426 t2.push_back(lr);427428 temp=temp+t2;429 }430 }431//cout<<"temp.size"<< temp.size()<<endl;432433if(temp.size()>0){434int k;435for(k=0;k<I_count;k++){//找⼀找项⽬集是否已经存在436if(cmp_vector(I[k],temp)){437break;438 }439 }440if(k==I_count){441//产⽣了新的项⽬集442 I[I_count] = temp;443/*444 cout<<"---------------------"<<endl;445 cout<<"新的项⽬集I"<<I_count<<endl;446 cout<<" I"<<i<<" -- "<<*it<<"->"<<"I"<<I_count<<endl<<endl; 447 showI(I[I_count]);//展⽰项⽬集448 cout<<"---------------------"<<endl;449*/450 cout<<" I"<<i<<" -- "<<*it<<"->"<<"I"<<I_count<<endl<<endl; 451 GOTO[i][*it] = I_count;//更新goto表452 I_count++;453 }else{454//项⽬集已经存在,需要⾃⼰指向⾃⼰455 cout<<" I"<<i<<" -- "<<*it<<"->"<<"I"<<k<<endl<<endl;456 GOTO[i][*it] = k;457458 }459460 }465 vector<CSS_LR1> temp;466467for(int j = 0;j<I[i].size();j++){468 CSS_LR1 lr = I[i][j];469470if(lr.num<lr.next.size()&&lr.next[lr.num]==*it){471 vector<CSS_LR1> t2;472 lr.num++;473 t2 = CLOSURE(lr);//闭包求出的结果不包含本⾝474 t2.insert(t2.begin(),lr);/////////求闭包遇到了⼀些问题475//showI(t2);476 temp=temp+t2;477 }478 }479//cout<<"temp.size"<< temp.size()<<endl;480if(temp.size()>0){481int k;482for(k=0;k<I_count;k++){//找⼀找项⽬集是否已经存在483if(cmp_vector(I[k],temp)){484break;485 }486 }487if(k==I_count){488//产⽣了新的项⽬集489 I[I_count] = temp;490/*491 cout<<"---------------------"<<endl;492 cout<<"新的项⽬集I"<<I_count<<endl;493 cout<<" I"<<i<<" -- "<<*it<<"->"<<"I"<<I_count<<endl<<endl;494 showI(I[I_count]);//展⽰项⽬集495 cout<<"---------------------"<<endl;496*/497 cout<<" I"<<i<<" -- "<<*it<<"->"<<"I"<<I_count<<endl<<endl;498 std::stringstream ss;499 ss<<I_count;500string s = ss.str();501 ACTION[i][*it] = "S"+s;//更新AVTION表502 I_count++;503 }else{504//项⽬集已经存在,需要⾃⼰指向⾃⼰505 cout<<" I"<<i<<" -- "<<*it<<"->"<<"I"<<k<<endl<<endl;506 std::stringstream ss;507 ss<<k;508string s = ss.str();509 ACTION[i][*it] = "S"+s;510511 }512513 }514 }515516517 }518519520 }521522void print_line(){523 cout<<"-----------------------------------------------------------------------------"<<endl;524 }525526527528void print_ACTION_GOTO(){529set<string>::iterator it;530 print_line();531 cout<<setw(27) << setiosflags(ios::right) <<"ACTION";532 cout<<setw(20) << setiosflags(ios::left)<<" GOTO"<<endl;533 print_line();534 cout<<setw(8)<<"项⽬集"<<"|";535536for(it=VT.begin();it!=VT.end();it++){537 cout<<setw(8)<<*it<<"|";538 }539 cout<<setw(8)<<"#"<<"|";540for(it=VN.begin();it!=VN.end();it++){541 cout<<setw(8)<<*it<<"|";542 }543 cout<<endl;544for(int j =0;j<I_count;j++){545 cout<<setw(6)<<"I"<<setw(2)<<j<<"|";546for(it=VT.begin();it!=VT.end();it++){547 cout<<setw(8)<<ACTION[j][*it]<<"|";548 }549 cout<<setw(8)<<ACTION[j]["#"]<<"|";550for(it=VN.begin();it!=VN.end();it++){551552if(GOTO[j][*it])//GOTO表为0553 cout<<setw(8)<<GOTO[j][*it]<<"|";554else{555 cout<<setw(8)<<""<<"|";556 }557 }558 cout<<endl;559 }560 print_line();561562 }563564565566//对栈容器进⾏输出,i=0,返回status中的字符串,i=1,返回sign中的字符串,i=2返回inputStr中的字符串567string vectTrancStr(int i,vector<int> status,vector<string> sign){568string buf;569int count = 0;570//输出状态栈571if(i == 0){572 vector<int>::iterator it =status.begin();573//将数字转化为字符串574string str,tempStr;575for(it;it!= status.end();it++){576 stringstream ss;577 ss << *it;578 ss >> tempStr;579 str+=tempStr;580 }581return str;586for(it ; it != sign.end() ;it++){587 buf += *it;588 count++;589 }590 }591592593string str(buf);594return str;595 }596597598599void Input_Analyse(){//输⼊句⼦,开始分析600601 vector<int> status;//定义状态栈602 vector<string> sign;//定义符号栈603604int step = 1; //步骤605string input;606 cout<<"请输⼊分析的字符串(请以#结尾):";607 cin>>input;//输⼊待分析的句⼦608 input = input+"#";609610 status.push_back(0);//把状态0⼊栈611//把#加⼊符号栈612 sign.push_back("#");613//输出初始栈状态614 cout<<setw(10)<<"步骤"<<setw(10)<<"状态栈"<<setw(10)<<"符号栈"<<setw(10)<<"输⼊串"<<setw(25)<<"动作说明"<<endl;615616int s =0;//初始状态617618int oldStatus;//保存之前的状态619620621string input_s; //获取初始符号622 input_s = input.substr(0,1);623624while(ACTION[s][input_s] != "acc"){//如果action[s][input_s] =="acc" ,则分析成功625//获取字符串626string str = ACTION[s][input_s];627//如果str为空,报错并返回628if(str.size() == 0){629 cout<<"出错";630return ;631 }632//获取S或r后⾯的数字633 stringstream ss;634 ss << str.substr(1);635 ss >> s;//新的状态号636//如果是移进637if(str.substr(0,1) == "S"){638 cout<<setw(10)<<step<<setw(10)<<vectTrancStr(0,status,sign)<<setw(10)<<vectTrancStr(1,status,sign)<<setw(10)<<input<<setw(10)<<"A"<<"CTION["<<status.back()<<","<<input_s<<"]=S"<<s<<","<<"状态"<<s<< 639 sign.push_back(input_s); //输⼊符号⼊栈640 input.erase(0,1);641 status.push_back(s);//将状态数字⼊栈642 }643//如果是规约644else if(str.substr(0,1) == "r"){645string kaitou;//产⽣式的头部646 kaitou = css[s].start;647int pop_num = css[s].next.size();//获取符号栈的出栈次数648649string r;650 stringstream ss;651 ss << s;652 ss >> r;653int oldStatus;//保存之前的状态654int status_size = status.size();655 oldStatus = status[status_size-1-pop_num];656 s=GOTO[oldStatus][kaitou];657 cout<<setw(10)<<step<<setw(10)<<vectTrancStr(0,status,sign)<<setw(10)<<vectTrancStr(1,status,sign)<<setw(10)<<input<<setw(10)<<(string)":产⽣式"+r+(string)"归约,GOTO("<<oldStatus<<","<<kaitou<<")="<<s<< 658//对符号栈进⾏出栈和状态栈进⾏出栈659while(pop_num--){660 sign.pop_back();661 status.pop_back();662 }663664 sign.push_back(kaitou);//再对产⽣式的开始符号⼊栈665 status.push_back(s);//再把新的状态⼊栈666 }667else{668//nothing669 }670671 step++; //步骤数加1672673 s = status.back();//获取栈顶状态674675 input_s = input.substr(0,1);//获取输⼊的字符676 }677 cout<<setw(10)<<step<<setw(10)<<vectTrancStr(0,status,sign)<<setw(10)<<vectTrancStr(1,status,sign)<<setw(10)<<input<<setw(10)<<"A"<<"cc:分析成功"<<endl;678679680 }681int main(){682 input();//输⼊⼆型⽂法683 GetFirst_and_Follow();//求First和Follow集合684 LR1_Analyse();685 print_ACTION_GOTO();//打印ACTION GOTO表686 Input_Analyse();//输⼊句⼦,开始分析687 }LR1.cpp代码的输⼊写的⽐较草率,可以⾃⾏修改⼀下,只要保存到相应的数据结构中,就不影响后⾯的LR1分析。

编译原理实验LL1分析

编译原理实验LL1分析
编译原理实验ll1分析基本的功能下面主要采用了ll1分析方法来进行语法分析先通过判断该文法是不是ll1文法如果不是先将其改写成ll1文法再将ll1文法改造成等价形式ll1分析表通过分析表来进行语法分析本程序的主要功能是对一个文法句子的生成过程进行分析
实验三语法分析---LL(1)分析器


1.用程序的方法实现语法分析的LL(1)方法。
}
void put_setence()
{
char ch;
int i=0;
while((ch=cin.get()) != '#') {
analyz_sentence[i] = ch;
i++;
}
analyz_sentence[i] = '#';
}
void init_stack()
{
stack[0] = '#';
return i;
}
return -1;
}
void reve()
{
strcpy(s, tp);
int i,j;
char t;
i=0;
while (s[i] != '\0')
++i;
--i;
if (s[i] == '\n')
--i;
j=0;
while (j<i)
{
t = s[j];
s[j] = s[i];
cout << "=>";
if (top == 'u')
pop();
}
void pop()
{

编译原理课程设计基于LL(1)法的条件语句语法语义分析程序

编译原理课程设计基于LL(1)法的条件语句语法语义分析程序

计算机科学与技术学院课程设计报告(2008~2009学年度第一学期)课程名称编译原理实验名称基于LL(1)法的条件语句语法语义分析程序姓名学号专业班级地点教师目录一.系统需求分析------------------------------------------------------------------------------------ 二.概念模型设计------------------------------------------------------------------------------------ 三.逻辑模型设计------------------------------------------------------------------------------------四.物理模型设计------------------------------------------------------------------------------------ 五.实验结果分析------------------------------------------------------------------------------------六.心得体会--------------------------------------------------------------------------------------------七.源代码------------------------------------------------------------------------------------------------一.系统需求分析通过设计,编制,调试一个语法及语义分析程序,加深对语法及语义分析原理的理解。

IF 〈布尔表达式〉THEN 〈赋值语句〉ELSE 〈赋值语句〉其中(1)、可以选择递归下降法、LL(1)、算符优先分析法、LR法完成以上任务,中间代码选用四元式。

编译原理-LR分析法(附源码)

编译原理-LR分析法(附源码)

LR分析实验报告一、实验项目名称LR分析二、实验目的掌握用LR 分析法对表达式文法进行自底向上语法分析的算法,加深对LR 分析法的三、实验环境Windows 10Microsoft Visual Studio 2015四、实验内容本次实验的SLR(1)文法为表达式拓广文法:(0)S’→E(1)E→E+T(2)E→T(3)T→T*F(4)T→F(5)F→(E)(6)F→i改进后的SLR(1)分析表如教材142 页图7.8。

编写识别表达式拓广文法的合法句子的SLR(1)分析程序,对输入的任意符号串,给出分析过程及分析结果。

分析过程要求输出步骤、状态栈、符号栈、输入串和语法动作。

如果该符号串不是表达式文法的合法句子,要给出尽量详细的错误提示。

五、实验步骤将改进后的SLR(1)分析表存到一个数组中,本次实验的文法是写在程序中的,不可改变,这种方法降低了实验代码的难度。

六、源程序清单、测试数据、结果#define_CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<string.h>char*action[12][6] = { /*ACTION*/"S5#",NULL,NULL,"S4#",NULL,NULL,NULL,"S6#",NULL,NULL,NULL,"acc",NULL,"r2#","S7#",NULL,"r2#","r2#",NULL,"r4#","r4#",NULL,"r4#","r4#","S5#",NULL,NULL,"S4#",NULL,NULL,NULL,"r6#","r6#",NULL,"r6#","r6#","S5#",NULL,NULL,"S4#",NULL,NULL,"S5#",NULL,NULL,"S4#",NULL,NULL,NULL,"S6#",NULL,NULL,"S11#",NULL,NULL,"r1#","S7#",NULL,"r1#","r1#",NULL,"r3#","r3#",NULL,"r3#","r3#",NULL,"r5#","r5#",NULL,"r5#","r5#", };int goto1[12][3] = {/*GOTO*/1,2,3,0,0,0,0,0,0,0,0,0,8,2,3,0,0,0,0,9,3,0,0,10,0,0,0,0,0,0,0,0,0,0,0,0 };char vt[6] = { 'i','+','(',')','*','#' };/*存放终结符*/char vn[3] = { 'E','T','F', };/*存放非终结符*/char *LR[7] = { "S->E#","E->E+T#","E->T#","T->T*F#","T->F#","F->(E)","F->i" };/*存放产生式*/int a[10];char b[10], c[10], c1;int top1, top2, top3, top, m, n;void lr() {int g, h, i, j, k, l, p, y, z, count;char x, copy[10], copy1[10];top1 = 0; top2 = 0; top3 = 0; top = 0;a[0] = 0; y = a[0]; b[0] = '#';count = 0;z = 0;printf("----------------请输入表达式(以#结尾)--------------\n");do {scanf("%c", &c1);c[top3] = c1;top3 = top3 + 1;} while (c1 != '#');printf("步骤\t状态栈\t\t符号栈\t\t输入串\t\tACTION\tGOTO\n");do {y = z; m = 0; n = 0; /*y,z指向状态栈栈顶*/g = top; j = 0; k = 0;x = c[top];count++;printf("%d\t", count);while (m <= top1) {/*输出状态栈*/printf("%d", a[m]);m = m + 1;}printf("\t\t");while (n <= top2) {/*输出符号栈*/ printf("%c", b[n]); n = n + 1; }printf("\t\t");while (g <= top3) {/*输出输入串*/ printf("%c", c[g]);g = g + 1;}printf("\t\t");while (x != vt[j] && j <= 6)j++;if (j == 6 && x != vt[j]){printf("error\n");return;}if (action[y][j] == NULL) {printf("error\n");return;}elsestrcpy(copy, action[y][j]);if (copy[0] == 'S'){/*处理移进*/z = copy[1] - '0';top1 = top1 + 1;top2 = top2 + 1;a[top1] = z;b[top2] = x;top = top + 1;i = 0;while (copy[i] != '#'){printf("%c", copy[i]); i++;}printf("\n");}if (copy[0] == 'r'){/*处理归约*/i = 0; while (copy[i] != '#'){printf("%c", copy[i]);i++;}h = copy[1] - '0';strcpy(copy1, LR[h]);while (copy1[0] != vn[k])k++;l = strlen(LR[h]) - 4;top1 = top1 - l + 1;top2 = top2 - l + 1;y = a[top1 - 1];p = goto1[y][k];a[top1] = p;b[top2] = copy1[0];z = p;printf("\t");printf("%d\n", p);}}while (action[y][j] != "acc");printf("acc\n");getchar();}七、实验小结和思考实现LR(1)文法很困难,我是直接将文法写在程序中直接输出分析表,而让程序实现对输入符号串的分析,在编程过程中也遇到了很多困难,如对某些终结符的动作或是规约函数的实现,最后通过上网查找参考资料,都得到了解决。

编译原理语法分析器实验报告

编译原理语法分析器实验报告

编译原理语法分析器实验报告西安邮电大学编译原理实验报告学院名称:计算机学院****:***实验名称:语法分析器的设计与实现班级:计科1405班学号:04141152时间:2017年5月12日把SELECT (i)存放到temp中结果返回1;1.构建好的预测分析表2.语法分析流程图一.实验结果正确运行结果:错误运行结果:二.设计技巧和心得体会这次实验编写了一个语法分析方法的程序,但是在LL(1)分析器的编写中我只达到了最低要求,就是自己手动输入的select集,first集,follow集然后通过程序将预测分析表构造出来,然后自己编写总控程序根据分析表进行分析。

通过本次试验,我能够设计一个简单的语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析,进一步掌握常用的语法分析方法。

还能选择最有代表性的语法分析方法,如LL(1) 语法分析程序、算符优先分析程序和LR分析分析程序。

三.源代码package com.LL1;import java.util.ArrayDeque;import java.util.Deque;/*** LL1文法分析器,已经构建好预测分析表,采用Deque实现* Created by HongWeiPC on 2017/5/12.*/public class LL1_Deque {//预测分析表private String[][] analysisTable = new String[][]{{"TE'", "", "", "TE'", "", ""},{"", "+TE'", "", "", "ε", "ε"},{"FT'", "", "", "FT'", "", ""},{"", "ε", "*FT'", "", "ε", "ε"},{"i", "", "", "(E)", "", ""}};//终结符private String[] VT = new String[]{"i", "+", "*", "(", ")", "#"};//非终结符private String[] VN = new String[]{"E", "E'", "T", "T'", "F"};//输入串strTokenprivate StringBuilder strToken = new StringBuilder("i*i+i");//分析栈stackprivate Deque<String> stack = new ArrayDeque<>();//shuru1保存从输入串中读取的一个输入符号,当前符号private String shuru1 = null;//X中保存stack栈顶符号private String X = null;//flag标志预测分析是否成功private boolean flag = true;//记录输入串中当前字符的位置private int cur = 0;//记录步数private int count = 0;public static void main(String[] args) {LL1_Deque ll1 = new LL1_Deque();ll1.init();ll1.totalControlProgram();ll1.printf();}//初始化private void init() {strToken.append("#");stack.push("#");System.out.printf("%-8s %-18s %-17s %s\n", "步骤", "符号栈", "输入串", "所用产生式");stack.push("E");curCharacter();System.out.printf("%-10d %-20s %-20s\n", count, stack.toString(), strToken.substring(cur, strToken.length()));}//读取当前栈顶符号private void stackPeek() {X = stack.peekFirst();}//返回输入串中当前位置的字母private String curCharacter() {shuru1 = String.valueOf(strToken.charAt(cur));return shuru1;}//判断X是否是终结符private boolean XisVT() {for (int i = 0; i < (VT.length - 1); i++) {if (VT[i].equals(X)) {return true;}}return false;}//查找X在非终结符中分析表中的横坐标private String VNTI() {int Ni = 0, Tj = 0;for (int i = 0; i < VN.length; i++) {if (VN[i].equals(X)) {Ni = i;}}for (int j = 0; j < VT.length; j++) {if (VT[j].equals(shuru1)) {Tj = j;}}return analysisTable[Ni][Tj];}//判断M[A,a]={X->X1X2...Xk}//把X1X2...Xk推进栈//X1X2...Xk=ε,不推什么进栈private boolean productionType() {return VNTI() != "";}//推进stack栈private void pushStack() {stack.pop();String M = VNTI();String ch;//处理TE' FT' *FT'特殊情况switch (M) {case "TE'":stack.push("E'");stack.push("T");break;case "FT'":stack.push("T'");stack.push("F");break;case "*FT'":stack.push("T'");stack.push("F");stack.push("*");break;case "+TE'":stack.push("E'");stack.push("T");stack.push("+");break;default:for (int i = (M.length() - 1); i >= 0; i--) {ch = String.valueOf(M.charAt(i));stack.push(ch);}break;}System.out.printf("%-10d %-20s %-20s %s->%s\n", (++count), stack.toString(), strToken.substring(cur, strToken.length()), X, M);}//总控程序private void totalControlProgram() {while (flag) {stackPeek(); //读取当前栈顶符号令X=栈顶符号if (XisVT()) {if (X.equals(shuru1)) {cur++;shuru1 = curCharacter();stack.pop();System.out.printf("%-10d %-20s %-20s \n", (++count), stack.toString(), strToken.substring(cur, strToken.length()));} else {ERROR();}} else if (X.equals("#")) {if (X.equals(shuru1)) {flag = false;} else {ERROR();}} else if (productionType()) {if (VNTI().equals("")) {ERROR();} else if (VNTI().equals("ε")) {stack.pop();System.out.printf("%-10d %-20s %-20s %s->%s\n", (++count), stack.toString(), strToken.substring(cur, strToken.length()), X, VNTI());} else {pushStack();}} else {ERROR();}}}//出现错误private void ERROR() {System.out.println("输入串出现错误,无法进行分析");System.exit(0);}//打印存储分析表private void printf() {if (!flag) {System.out.println("****分析成功啦!****");} else {System.out.println("****分析失败了****");}}}。

编译原理中LL(1)文法的源代码汇总

编译原理中LL(1)文法的源代码汇总

一. 实验目的1.掌握LL(1分析法的基本原理2.掌握LL(1分析表的构造方法3.掌握LL(1驱动程序的构造方法二. 实验内容及要求根据某一文法编制调试LL(1)分析程序,以便对任意输入的符号串进行分析。

本次实验的目的主要是加深对预测分析LL(1)分析法的理解。

例:对下列文法,用LL(1)分析法对任意输入的符号串进行分析:(1)E->TG(2)G->+TG|—TG(3)G->ε(4)T->FS(5)S->*FS|/FS(6)S->ε(7)F->(E(8)F->i输出的格式如下:(1LL(1)分析程序,编制人:姓名,学号,班级(2输入一以#结束的符号串(包括+—*/()i#:在此位置输入符号串(3输出过程如下:步骤分析栈剩余输入串所用产生式1 E i+i*i# E->TG(4输入符号串为非法符号串(或者为合法符号串备注:(1在“所用产生式”一列中如果对应有推导则写出所用产生式;如果为匹配终结符则写明匹配的终结符;如分析异常出错则写为“分析出错”;若成功结束则写为“分析成功”。

(2 在此位置输入符号串为用户自行输入的符号串。

(3上述描述的输出过程只是其中一部分的。

注意:1.表达式中允许使用运算符(+-*/)、分割符(括号)、字符i,结束符#;2.如果遇到错误的表达式,应输出错误提示信息(该信息越详细越好);3.对学有余力的同学,测试用的表达式事先放在文本文件中,一行存放一个表达式,同时以分号分割。

同时将预期的输出结果写在另一个文本文件中,以便和输出进行对照;4.可采用的其它的文法。

三. 实验过程LL(1分析法的实验源程序代码如下:#include#include#include#includechar A[20];/*分析栈*/char B[20];/*剩余串*/char v1[20]={'i','+','*','(','','#'};/*终结符 */char v2[20]={'E','G','T','S','F'};/*非终结符 */int j=0,b=0,top=0,l;/*L为输入串长度 */typedef struct type/*产生式类型定义 */{char origin;/*大写字符 */char array[5];/*产生式右边字符 */int length;/*字符个数 */}type;type e,t,g,g1,s,s1,f,f1;/*结构体变量 */ type C[10][10];/*预测分析表 */void print(/*输出分析栈 */{int a;/*指针*/for(a=0;a<=top+1;a++printf("%c",A[a];printf("\t\t";}/*print*/void print1(/*输出剩余串*/{int j;for(j=0;j 输出对齐符 */printf(" ";for(j=b;j<=l;j++printf("%c",B[j];printf("\t\t\t";}/*print1*/void main({int m,n,k=0,flag=0,finish=0;char ch,x;type cha;/*用来接受C[m][n]*/ /*把文法产生式赋值结构体*/ e.origin='E';strcpy(e.array,"TG";e.length=2;t.origin='T';strcpy(t.array,"FS";t.length=2;g.origin='G';strcpy(g.array,"+TG";g.length=3;g1.origin='G';g1.array[0]='^';g1.length=1;s.origin='S';strcpy(s.array,"*FS";s.length=3;s1.origin='S';s1.array[0]='^';s1.length=1;f.origin='F';strcpy(f.array,"(E";f.length=3;f1.origin='F';f1.array[0]='i';f1.length=1;for(m=0;m<=4;m++/*初始化分析表*/for(n=0;n<=5;n++C[m][n].origin='N';/*全部赋为空*//*填充分析表*/C[0][0]=e;C[0][3]=e;C[1][1]=g;C[1][4]=g1;C[1][5]=g1;C[2][0]=t;C[2][3]=t;C[3][1]=s1;C[3][2]=s;C[3][4]=C[3][5]=s1;C[4][0]=f1;C[4][3]=f;printf("提示:本程序只能对由'i','+','*','(',''构成的以'#'结束的字符串进行分析,\n"; printf("请输入要分析的字符串:";do/*读入分析串*/{scanf("%c",&ch;if ((ch!='i' &&(ch!='+' &&(ch!='*'&&(ch!='('&&(ch!=''&&(ch!='#'{printf("输入串中有非法字符\n";exit(1;}B[j]=ch;j++;}while(ch!='#';l=j;/*分析串长度*/ch=B[0];/*当前分析字符*/A[top]='#'; A[++top]='E';/*'#','E'进栈*/printf("步骤\t\t分析栈 \t\t剩余字符 \t\t所用产生式 \n"; do{x=A[top--];/*x为当前栈顶字符*/printf("%d",k++;printf("\t\t";for(j=0;j<=5;j++/*判断是否为终结符*/if(x==v1[j]{flag=1;break;}if(flag==1/*如果是终结符*/{if(x=='#'{finish=1;/*结束标记*/printf("acc!\n";/*接受 */getchar(;getchar(;exit(1;}/*if*/if(x==ch{print(;print1(;printf("%c匹配\n",ch;ch=B[++b];/*下一个输入字符*/flag=0;/*恢复标记*/}/*if*/else/*出错处理*/{print(;print1(;printf("%c出错\n",ch;/*输出出错终结符*/ exit(1;}/*else*/}/*if*/else/*非终结符处理*/{for(j=0;j<=4;j++if(x==v2[j]{m=j;/*行号*/break;}for(j=0;j<=5;j++if(ch==v1[j]{n=j;/*列号*/break;}cha=C[m][n];if(cha.origin!='N'/*判断是否为空*/{print(;print1(;printf("%c->",cha.origin;/*输出产生式*/for(j=0;jprintf("%c",cha.array[j];printf("\n";for(j=(cha.length-1;j>=0;j--/*产生式逆序入栈*/ A[++top]=cha.array[j];if(A[top]=='^'/*为空则不进栈*/top--;}/*if*/else/*出错处理*/{print(;print1(;printf("%c出错\n",x;/*输出出错非终结符*/exit(1;}/*else*/}/*else*/}while(finish==0;}/*main*/程序的运行结果如下:四. 实验心得经过这个实验的练习,通过对程序的分析,让我进一步了解LL(1)算法的思想以及它的进一步程序实现,让我对它的了解从简单的理论上升到程序实现的级别,有理论上升到实际,让我更清楚它的用途。

LL(1)文法分析表的构造和分析过程示例

LL(1)文法分析表的构造和分析过程示例

LL(1)⽂法分析表的构造和分析过程⽰例在考完编译原理之后才弄懂,悲哀啊。

不过懂了就好,知识吗,不能局限于考试。

⽂法:E→TE'E'→+TE'|εT→FT 'T'→*FT'|εF→id| (E)⼀、⾸先判断是不是 LL(1)⽂法--------------------------------------------------------------------------------------------------------⽂法G的任意两个具有相同左部的产⽣式 A --> α|β满⾜下列条件:1、如果α和β不能同时推导出ε,则 FIRST(α)∩FIRST(β) = 空2、α和β⾄多有⼀个能推导出ε3、如果β --*--> ε ,则 FIRST(α)∩ FOLLOW(A)=空--------------------------------------------------------------------------------------------------------对于 E'→+TE'|ε,显然ε --> ε, First(+TE') = {+} ,Follow(E') = {{),#} 显然⼆者交集为空满⾜。

对于 F→id|(E) ,First(id) = {id} First((E)) = {(} 显然⼆者交集为空满⾜。

所以该⽂法是LL(1)⽂法。

⼆、计算出First集和Follow集参考:三、构建LL(1)分析表输⼊:⽂法G输出:分析表M步骤:1、对G中任意⼀个产⽣式 A --> α执⾏第2步和第3步2、for 任意a ∈ First(α),将 A --> α填⼊M[A,a]3、if ε∈ First(α) then 任意a ∈ Follow(A),将 A --> α填⼊M[A,a]if ε∈ First(α) & # ∈Follow(A), then 将 A --> α填⼊M[A,#] (觉得这步没⽤)4、将所有没有定义的M[A,b] 标上出错标志(留空也可以)--------------------------------------------------------------------------------------------------------过程就不赘述了,结果:四、分析过程步骤:1、如果 X = a = # 则分析成功并停机2、如果 X = a != # 则弹出栈顶符号X, 并将输⼊指针移到下⼀个符号上3、如果 X != a,查询分析表M[X,a] , 如果 M[X,a] = {X --> UVW},则⽤UVW (U在栈顶) 替换栈顶符号 X。

编译原理_LL(1)文法源代码(实验三)

编译原理_LL(1)文法源代码(实验三)

一、实验目的及要求1.把握LL(1)分析法的大体原理;2.把握LL(1)分析表的构造方式;3.用LL(1)分析法分析高级语言表达式。

4、了解LL(1)分析器的工作进程。

文法:无二义性的算术表达式的文法(1)把词法分析作为语法分析的子程序实现(5分)(2)独立的语法分析程序(4分)(3)对表达式文法排除左递归、构造LL(1)分析表(4)LL(1)分析表能够直接输入(4分),也能够用程序实现(5分)(5)给一个表达式,给出分析进程(分析栈、输入串、所用规那么)(4分)(6)生成一个棵语法树(5分)用二叉树的形式表示出来二、实验内容及原理一、实验原理(1)、LL(1)文法的概念LL(1)分析法属于确信的自顶向下分析方式。

LL(1)的含义是:第一个L说明自顶向下分析是从左向右扫描输入串,第2个L说明分析进程中将利用最左推导,1说明只需向右看一个符号即可决定如何推导,即选择哪个产生式(规那么)进行推导。

LL(1)文法的判别需要依次计算FIRST集、FOLLOW集和SELLECT集,然后判定是不是为LL(1)文法,最后再进行句子分析。

需要预测分析器对所给句型进行识别。

即在LL(1)分析法中,每当在符号栈的栈顶显现非终极符时,要预测用哪个产生式的右部去替换该非终极符;当显现终结符时,判定其与剩余输入串的第一个字符是不是匹配,若是匹配,那么继续分析,不然报错。

LL(1)分析方式要求文法知足如下条件:关于任一非终极符A的两个不同产生式A→α,A→β,都要知足下面条件:SELECT(A→α)∩SELECT(A→β)=∅(2)、预测分析表构造LL(1)分析表的作用是对当前非终极符和输入符号确信应该选择用哪个产生式进行推导。

它的行对应文法的非终极符,列对应终极符,表中的值有两种:一是产生式的右部的字符串,一是null。

假设用M表示LL(1)分析表,那么M可表示如下:M: VN×VT→P∪{Error}M(A, t) = A→α,当t∈select(A→α) ,不然M(A, t) = Error其中P表示所有产生式的集合。

编译原理实验二:LL(1)语法分析器

编译原理实验二:LL(1)语法分析器

编译原理实验⼆:LL(1)语法分析器⼀、实验要求 1. 提取左公因⼦或消除左递归(实现了消除左递归) 2. 递归求First集和Follow集 其它的只要按照课本上的步骤顺序写下来就好(但是代码量超多...),下⾯我贴出实验的⼀些关键代码和算法思想。

⼆、基于预测分析表法的语法分析 2.1 代码结构 2.1.1 Grammar类 功能:主要⽤来处理输⼊的⽂法,包括将⽂法中的终结符和⾮终结符分别存储,检测直接左递归和左公因⼦,消除直接左递归,获得所有⾮终结符的First集,Follow集以及产⽣式的Select集。

#ifndef GRAMMAR_H#define GRAMMAR_H#include <string>#include <cstring>#include <iostream>#include <vector>#include <set>#include <iomanip>#include <algorithm>using namespace std;const int maxn = 110;//产⽣式结构体struct EXP{char left; //左部string right; //右部};class Grammar{public:Grammar(); //构造函数bool isNotTer(char x); //判断是否是终结符int getTer(char x); //获取终结符下标int getNonTer(char x); //获取⾮终结符下标void getFirst(char x); //获取某个⾮终结符的First集void getFollow(char x); //获取某个⾮终结符的Follow集void getSelect(char x); //获取产⽣式的Select集void input(); //输⼊⽂法void scanExp(); //扫描输⼊的产⽣式,检测是否有左递归和左公因⼦void remove(); //消除左递归void solve(); //处理⽂法,获得所有First集,Follow集以及Select集void display(); //打印First集,Follow集,Select集void debug(); //⽤于debug的函数~Grammar(); //析构函数protected:int cnt; //产⽣式数⽬EXP exp[maxn]; //产⽣式集合set<char> First[maxn]; //First集set<char> Follow[maxn]; //Follow集set<char> Select[maxn]; //select集vector<char> ter_copy; //去掉$的终结符vector<char> ter; //终结符vector<char> not_ter; //⾮终结符};#endif 2.1.2 AnalyzTable类 功能:得到预测分析表,判断输⼊的⽂法是否是LL(1)⽂法,⽤预测分析表法判断输⼊的符号串是否符合刚才输⼊的⽂法,并打印出分析过程。

实验5-LL(1)语法分析程序的设计与实现(C语言)

实验5-LL(1)语法分析程序的设计与实现(C语言)

实验五LL(1)文法识别程序设计一、实验目的通过LL(1)文法识别程序的设计理解自顶向下的语法分析思想。

二、实验重难点FIRST集合、FOLLOW集合、SELECT集合元素的求解,预测分析表的构造。

三、实验内容与要求实验内容:1.阅读并理解实验案例中LL(1)文法判别的程序实现;2.参考实验案例,完成简单的LL(1)文法判别程序设计。

四、实验学时4课时五、实验设备与环境C语言编译环境六、实验案例1.实验要求参考教材93页预测分析方法,94页图5.11 预测分析程序框图,编写表达式文法的识别程序。

要求对输入的LL(1)文法字符串,程序能自动判断所给字符串是否为所给文法的句子,并能给出分析过程。

表达式文法为:E→E+T|TT→T*F|FF→i|(E)2.参考代码为了更好的理解代码,建议将图5.11做如下标注:/* 程序名称: LL(1)语法分析程序 *//* E->E+T|T *//* T->T*F|F *//* F->(E)|i *//*目的: 对输入LL(1)文法字符串,本程序能自动判断所给字符串是否为所给文法的句子,并能给出分析过程。

/********************************************//* 程序相关说明 *//* A=E' B=T' *//* 预测分析表中列号、行号 *//* 0=E 1=E' 2=T 3=T' 4=F *//* 0=i 1=+ 2=* 3=( 4=) 5=# *//************************************/#include"iostream"#include "stdio.h"#include "malloc.h"#include "conio.h"/*定义链表这种数据类型参见:*/struct Lchar{char char_ch;struct Lchar *next;}Lchar,*p,*h,*temp,*top,*base;/*p指向终结符线性链表的头结点,h指向动态建成的终结符线性链表节点,top和base分别指向非终结符堆栈的顶和底*/char curchar; //存放当前待比较的字符:终结符char curtocmp; //存放当前栈顶的字符:非终结符int right;int table[5][6]={{1,0,0,1,0,0},{0,1,0,0,1,1},{1,0,0,1,0,0},{0,1,1,0,1,1},{1,0,0,1,0,0}};/*存放预测分析表,1表示有产生式,0表示无产生式。

编译原理:FOR循环语句的翻译程序设计LL(1)法、输出四元式(附源代码)

编译原理:FOR循环语句的翻译程序设计LL(1)法、输出四元式(附源代码)

学号:课程设计FOR循环语句的翻译程序设计题目(LL(1)法、输出四元式)学院计算机科学与技术专业计算机科学与技术班级计算机0901班姓名指导教师2012 年01 月03 日课程设计任务书学生姓名:专业班级:计算机0901班指导教师:工作单位:计算机科学与技术学院题目: FOR循环语句的翻译程序设计(LL(1)法、输出四元式)初始条件:理论:学完编译课程,掌握一种计算机高级语言的使用。

实践:计算机实验室提供计算机及软件环境。

如果自己有计算机可以在其上进行设计。

要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)(1)写出符合给定的语法分析方法的文法及属性文法。

(2)完成题目要求的中间代码四元式的描述。

(3)写出给定的语法分析方法的思想,完成语法分析和语义分析程序设计。

(4)编制好分析程序后,设计若干用例,上机测试并通过所设计的分析程序。

(5)设计报告格式按附件要求书写。

课程设计报告书正文的内容应包括:1 系统描述(问题域描述);2 文法及属性文法的描述;3 语法分析方法描述及语法分析表设计;4 按给定的题目给出中间代码形式的描述及中间代码序列的结构设计;5 编译系统的概要设计;6 详细的算法描述(流程图或伪代码);7 软件的测试方法和测试结果;8 研制报告(研制过程,本设计的评价、特点、不足、收获与体会等);9 参考文献(按公开发表的规范书写)。

时间安排:设计安排一周:周1、周2:完成系统分析及设计。

周3、周4:完成程序调试及测试。

周5:撰写课程设计报告。

设计验收安排:设计周的星期五第1节课开始到实验室进行上机验收。

设计报告书收取时间:设计周的次周星期一上午10点。

指导教师签名: 2011年11月18日系主任(或责任教师)签名: 2011年11月18日FOR循环语句的翻译程序设计——LL(1)法、输出四元式1.系统描述1.1问题描述用LL(1)法设计、编制、调试一个FOR(表达式1;表达式2;表达式3)〈赋值语句〉的语法及语义分析程序,输出四元式。

LL(1)语法分析程序

LL(1)语法分析程序

《编译原理》上机实验报告题目:LL(1)语法分析程序1.设计要求(1)对输入文法,它能判断是否为LL(1)文法,若是,则转(2);否则报错并终止;(2)输入已知文法,由程序自动生成它的LL(1)分析表;(3)对于给定的输入串,应能判断识别该串是否为给定文法的句型。

2.分析该程序可分为如下几步:(1)读入文法(2)判断正误(3)若无误,判断是否为LL(1)文法(4)若是,构造分析表;(5)由总控算法判断输入符号串是否为该文法的句型。

3.流程图4.源程序LL1语法分析程序#include<stdio.h>#include<string.h>int count=0; /*分解的产生式的个数*/int number; /*所有终结符和非终结符的总数*/char start; /*开始符号*/char termin[50]; /*终结符号*/char non_ter[50]; /*非终结符号*/char v[50]; /*所有符号*/char left[50]; /*左部*/char right[50][50]; /*右部*/char first[50][50],follow[50][50]; /*各产生式右部的FIRST和左部的FOLLOW集合*/ char first1[50][50]; /*所有单个符号的FIRST集合*/char select[50][50]; /*各单个产生式的SELECT集合*/char f[50],F[50]; /*记录各符号的FIRST和FOLLOW是否已求过*/char empty[20]; /*记录可直接推出^的符号*/char TEMP[50]; /*求FOLLOW时存放某一符号串的FIRST集合*/int validity=1; /*表示输入文法是否有效*/int ll=1; /*表示输入文法是否为LL(1)文法*/int M[20][20]; /*分析表*/char choose; /*用户输入时使用*/char empt[20]; /*求_emp()时使用*/char fo[20]; /*求FOLLOW集合时使用*//*******************************************判断一个字符是否在指定字符串中********************************************/int in(char c,char *p){//int i;size_t i;if(strlen(p)==0)return(0);for(i=0;;i++){if(p[i]==c)return(1); /*若在,返回1*/if(i==strlen(p))return(0); /*若不在,返回0*/}}/*******************************************得到一个不是非终结符的符号********************************************/char c(){char c='A';while(in(c,non_ter)==1)c++;return(c);}分解含有左递归的产生式********************************************/void recur(char *point){ /*完整的产生式在point[]中*/int j,m=0,n=3,k;char temp[20],ch;ch=c(); /*得到一个非终结符*/k=strlen(non_ter);non_ter[k]=ch;non_ter[k+1]='\0';for(j=0;size_t(j)<=strlen(point)-1;j++){if(point[n]==point[0]){ /*如果'|'后的首符号和左部相同*/ for(j=n+1;size_t(j)<=strlen(point)-1;j++){while(point[j]!='|'&&point[j]!='\0')temp[m++]=point[j++];left[count]=ch;memcpy(right[count],temp,m);right[count][m]=ch;right[count][m+1]='\0';m=0;count++;if(point[j]=='|'){n=j+1;break;}}}else{ /*如果'|'后的首符号和左部不同*/ left[count]=ch;right[count][0]='^';right[count][1]='\0';count++;for(j=n;size_t(j)<=strlen(point)-1;j++){if(point[j]!='|')temp[m++]=point[j];else{left[count]=point[0];memcpy(right[count],temp,m);right[count][m]=ch;right[count][m+1]='\0';m=0;count++;}}left[count]=point[0];memcpy(right[count],temp,m);right[count][m]=ch;right[count][m+1]='\0';count++;m=0;}}}/*******************************************分解不含有左递归的产生式********************************************/void non_re(char *point){int m=0,j;char temp[20];for(j=3;size_t(j)<=strlen(point)-1;j++){if(point[j]!='|')temp[m++]=point[j];else{left[count]=point[0];memcpy(right[count],temp,m);right[count][m]='\0';m=0;count++;}}left[count]=point[0];memcpy(right[count],temp,m);right[count][m]='\0';count++;m=0;}/*******************************************读入一个文法********************************************/char grammer(char *t,char *n,char *left,char right[50][50]) {char vn[50],vt[50];char s;char p[50][50];printf("\n请输入文法的非终结符号串:");scanf("%s",vn);getchar();i=strlen(vn);memcpy(n,vn,i);n[i]='\0';printf("请输入文法的终结符号串:");scanf("%s",vt);getchar();i=strlen(vt);memcpy(t,vt,i);t[i]='\0';printf("请输入文法的开始符号:");scanf("%c",&s);getchar();printf("请输入文法产生式的条数:");scanf("%d",&i);getchar();for(j=1;j<=i;j++){printf("请输入文法的第%d条(共%d条)产生式:",j,i);scanf("%s",p[j-1]);getchar();}for(j=0;j<=i-1;j++)if(p[j][1]!='-'||p[j][2]!='>'){ printf("\ninput error!");validity=0;return('\0');} /*检测输入错误*/for(k=0;k<=i-1;k++){ /*分解输入的各产生式*/if(p[k][3]==p[k][0])recur(p[k]);elsenon_re(p[k]);}return(s);}/*******************************************将单个符号或符号串并入另一符号串********************************************/void merge(char *d,char *s,int type){ /*d是目标符号串,s是源串,type=1,源串中的' ^ '一并并入目串;type=2,源串中的' ^ '不并入目串*/int i,j;for(i=0;size_t(i)<=strlen(s)-1;i++)if(type==2&&s[i]=='^');else{for(j=0;;j++){if(size_t(j)<strlen(d)&&s[i]==d[j])break;if(size_t(j)==strlen(d)){d[j]=s[i];d[j+1]='\0';break;}}}}}/*******************************************求所有能直接推出^的符号********************************************/void emp(char c){ /*即求所有由' ^ '推出的符号*/ char temp[10];int i;for(i=0;i<=count-1;i++){if(right[i][0]==c&&strlen(right[i])==1){temp[0]=left[i];temp[1]='\0';merge(empty,temp,1);emp(left[i]);}}}/*******************************************求某一符号能否推出' ^ '********************************************/int _emp(char c){ /*若能推出,返回1;否则,返回0*/ int i,j,k,result=1,mark=0;char temp[20];temp[0]=c;temp[1]='\0';merge(empt,temp,1);if(in(c,empty)==1)for(i=0;;i++){if(i==count)return(0);if(left[i]==c) /*找一个左部为c的产生式*/{j=strlen(right[i]); /*j为右部的长度*/if(j==1&&in(right[i][0],empty)==1)return(1);else if(j==1&&in(right[i][0],termin)==1)return(0);else{for(k=0;k<=j-1;k++)if(in(right[i][k],empt)==1)mark=1;if(mark==1)continue;else{for(k=0;k<=j-1;k++){result*=_emp(right[i][k]);temp[0]=right[i][k];temp[1]='\0';merge(empt,temp,1);}}}if(result==0&&i<count)continue;else if(result==1&&i<count)return(1);}}}/*******************************************判断读入的文法是否正确********************************************/int judge(){int i,j;for(i=0;i<=count-1;i++){if(in(left[i],non_ter)==0){ /*若左部不在非终结符中,报错*/ printf("\nerror1!");return(0);}for(j=0;size_t(j)<=strlen(right[i])-1;j++){if(in(right[i][j],non_ter)==0&&in(right[i][j],termin)==0&&right[i][j]!='^'){ /*若右部某一符号不在非终结符、终结符中且不为' ^ ',报错*/ printf("\nerror2!");validity=0;return(0);}}}return(1);}/*******************************************求单个符号的FIRST********************************************/void first2(int i){ /*i为符号在所有输入符号中的序号*/char c,temp[20];int j,k,m;c=v[i];char ch='^';emp(ch);if(in(c,termin)==1) /*若为终结符*/{first1[i][0]=c;first1[i][1]='\0';}else if(in(c,non_ter)==1) /*若为非终结符*/{for(j=0;j<=count-1;j++){if(left[j]==c){if(in(right[j][0],termin)==1||right[j][0]=='^'){temp[0]=right[j][0];temp[1]='\0';merge(first1[i],temp,1);}else if(in(right[j][0],non_ter)==1){if(right[j][0]==c)continue;for(k=0;;k++)if(v[k]==right[j][0])if(f[k]=='0'){first2(k);f[k]='1';}merge(first1[i],first1[k],2);for(k=0;size_t(k)<=strlen(right[j])-1;k++){empt[0]='\0';if(_emp(right[j][k])==1&&size_t(k)<strlen(right[j])-1){for(m=0;;m++)if(v[m]==right[j][k+1])break;if(f[m]=='0'){first2(m);f[m]='1';}merge(first1[i],first1[m],2);}else if(_emp(right[j][k])==1&&size_t(k)==strlen(right[j])-1){temp[0]='^';temp[1]='\0';merge(first1[i],temp,1);}elsebreak;}}}}}f[i]='1';}/*******************************************求各产生式右部的FIRST********************************************/void FIRST(int i,char *p){int length;int j,k,m;char temp[20];length=strlen(p);if(length==1) /*如果右部为单个符号*/{{if(i>=0){first[i][0]='^';first[i][1]='\0';}else{TEMP[0]='^';TEMP[1]='\0';}}else{for(j=0;;j++)if(v[j]==p[0])break;if(i>=0){memcpy(first[i],first1[j],strlen(first1[j]));first[i][strlen(first1[j])]='\0';}else{memcpy(TEMP,first1[j],strlen(first1[j]));TEMP[strlen(first1[j])]='\0';}}}else /*如果右部为符号串*/{for(j=0;;j++)if(v[j]==p[0])break;if(i>=0)merge(first[i],first1[j],2);elsemerge(TEMP,first1[j],2);for(k=0;k<=length-1;k++){empt[0]='\0';if(_emp(p[k])==1&&k<length-1){for(m=0;;m++)if(v[m]==right[i][k+1])break;if(i>=0)elsemerge(TEMP,first1[m],2);}else if(_emp(p[k])==1&&k==length-1){temp[0]='^';temp[1]='\0';if(i>=0)merge(first[i],temp,1);elsemerge(TEMP,temp,1);}else if(_emp(p[k])==0)break;}}}/*******************************************求各产生式左部的FOLLOW********************************************/void FOLLOW(int i){int j,k,m,n,result=1;char c,temp[20];c=non_ter[i]; /*c为待求的非终结符*/temp[0]=c;temp[1]='\0';merge(fo,temp,1);if(c==start){ /*若为开始符号*/temp[0]='#';temp[1]='\0';merge(follow[i],temp,1);}for(j=0;j<=count-1;j++){if(in(c,right[j])==1) /*找一个右部含有c的产生式*/{for(k=0;;k++)if(right[j][k]==c)break; /*k为c在该产生式右部的序号*/for(m=0;;m++)if(v[m]==left[j])break; /*m为产生式左部非终结符在所有符号中的序号*/ if(size_t(k)==strlen(right[j])-1){ /*如果c在产生式右部的最后*/if(in(v[m],fo)==1){merge(follow[i],follow[m],1);continue;}if(F[m]=='0'){FOLLOW(m);F[m]='1';}merge(follow[i],follow[m],1);}else{ /*如果c不在产生式右部的最后*/for(n=k+1;size_t(n)<=strlen(right[j])-1;n++){empt[0]='\0';result*=_emp(right[j][n]);}if(result==1){ /*如果右部c后面的符号串能推出^*/if(in(v[m],fo)==1){ /*避免循环递归*/merge(follow[i],follow[m],1);continue;}if(F[m]=='0'){FOLLOW(m);F[m]='1';}merge(follow[i],follow[m],1);}for(n=k+1;size_t(n)<=strlen(right[j])-1;n++)temp[n-k-1]=right[j][n];temp[strlen(right[j])-k-1]='\0';FIRST(-1,temp);merge(follow[i],TEMP,2);}}}F[i]='1';}/*******************************************判断读入文法是否为一个LL(1)文法********************************************/int ll1(){int i,j,length,result=1;char temp[50];for(j=0;j<=49;j++){ /*初始化*/first[j][0]='\0';follow[j][0]='\0';first1[j][0]='\0';select[j][0]='\0';TEMP[j]='\0';temp[j]='\0';f[j]='0';F[j]='0';}for(j=0;size_t(j)<=strlen(v)-1;j++)first2(j); /*求单个符号的FIRST集合*/ printf("\nfirst1:");for(j=0;size_t(j)<=strlen(v)-1;j++)printf("%c:%s ",v[j],first1[j]);printf("\nempty:%s",empty);printf("\n:::\n_emp:");for(j=0;size_t(j)<=strlen(v)-1;j++)printf("%d ",_emp(v[j]));for(i=0;i<=count-1;i++)FIRST(i,right[i]); /*求FIRST*/printf("\n");for(j=0;size_t(j)<=strlen(non_ter)-1;j++){ /*求FOLLOW*/if(fo[j]==0){fo[0]='\0';FOLLOW(j);}}printf("\nfirst:");for(i=0;i<=count-1;i++)printf("%s ",first[i]);printf("\nfollow:");for(i=0;size_t(i)<=strlen(non_ter)-1;i++)printf("%s ",follow[i]);for(i=0;i<=count-1;i++){ /*求每一产生式的SELECT集合*/ memcpy(select[i],first[i],strlen(first[i]));select[i][strlen(first[i])]='\0';for(j=0;size_t(j)<=strlen(right[i])-1;j++)result*=_emp(right[i][j]);if(strlen(right[i])==1&&right[i][0]=='^')result=1;if(result==1){for(j=0;;j++)if(v[j]==left[i])break;merge(select[i],follow[j],1);}}printf("\nselect:");for(i=0;i<=count-1;i++)printf("%s ",select[i]);memcpy(temp,select[0],strlen(select[0]));temp[strlen(select[0])]='\0';for(i=1;i<=count-1;i++){ /*判断输入文法是否为LL(1)文法*/length=strlen(temp);if(left[i]==left[i-1]){merge(temp,select[i],1);if(strlen(temp)<length+strlen(select[i]))return(0);}else{temp[0]='\0';memcpy(temp,select[i],strlen(select[i]));temp[strlen(select[i])]='\0';}}return(1);}/*******************************************构造分析表M********************************************/void MM(){int i,j,k,m;for(i=0;i<=19;i++)for(j=0;j<=19;j++)M[i][j]=-1;i=strlen(termin);termin[i]='#'; /*将#加入终结符数组*/termin[i+1]='\0';for(i=0;i<=count-1;i++){for(m=0;;m++)if(non_ter[m]==left[i])break; /*m为产生式左部非终结符的序号*/ for(j=0;size_t(j)<=strlen(select[i])-1;j++){if(in(select[i][j],termin)==1){for(k=0;;k++)if(termin[k]==select[i][j])break; /*k为产生式右部终结符的序号*/ M[m][k]=i;}}}}/*******************************************总控算法********************************************/void syntax(){int i,j,k,m,n,p,q;char ch;char S[50],str[50];printf("请输入该文法的句型:");scanf("%s",str);getchar();i=strlen(str);str[i]='#';str[i+1]='\0';S[0]='#';S[1]=start;S[2]='\0';j=0;ch=str[j];while(1){if(in(S[strlen(S)-1],termin)==1){if(S[strlen(S)-1]!=ch){printf("\n该符号串不是文法的句型!");return;}else if(S[strlen(S)-1]=='#'){printf("\n该符号串是文法的句型.");return;}else{S[strlen(S)-1]='\0';j++;ch=str[j];}}else{for(i=0;;i++)if(non_ter[i]==S[strlen(S)-1])break;for(k=0;;k++){if(termin[k]==ch)break;if(size_t(k)==strlen(termin)){printf("\n词法错误!");return;}}if(M[i][k]==-1){printf("\n语法错误!");return;}else{m=M[i][k];if(right[m][0]=='^')S[strlen(S)-1]='\0';else{p=strlen(S)-1;q=p;for(n=strlen(right[m])-1;n>=0;n--)S[p++]=right[m][n];S[q+strlen(right[m])]='\0';}}}printf("\nS:%s str:",S);for(p=j;size_t(p)<=strlen(str)-1;p++)printf("%c",str[p]);printf(" ");}}/*******************************************一个用户调用函数********************************************/void menu(){syntax();printf("\n是否继续?(y or n):");scanf("%c",&choose);getchar();while(choose=='y'){menu();}}/*******************************************主函数********************************************/void main(){int i,j;start=grammer(termin,non_ter,left,right); /*读入一个文法*/ printf("count=%d",count);printf("\nstart:%c",start);strcpy(v,non_ter);strcat(v,termin);printf("\nv:%s",v);printf("\nnon_ter:%s",non_ter);printf("\ntermin:%s",termin);printf("\nright:");for(i=0;i<=count-1;i++)printf("%s ",right[i]);printf("\nleft:");for(i=0;i<=count-1;i++)printf("%c ",left[i]);if(validity==1)validity=judge();printf("\nvalidity=%d",validity);if(validity==1){printf("\n文法有效");ll=ll1();printf("\nll=%d",ll);if(ll==0)printf("\n该文法不是一个LL1文法!");else{MM();printf("\n");for(i=0;i<=19;i++)for(j=0;j<=19;j++)if(M[i][j]>=0)printf("M[%d][%d]=%d ",i,j,M[i][j]);printf("\n");menu();}}}5.执行结果(1)输入一个文法(2)输入一个符号串(3)再次输入一个符号串,然后退出程序。

LL(1)文法判断程序java代码

LL(1)文法判断程序java代码

LL(1)文法判断程序java代码分为两个类import .ArrayList;import .HashMap;import .HashSet;import .Stack;public class LL_1 {public HashMap<Character, HashSet<Character>> firstSet = new HashMap<Character, HashSet<Character>>();public HashMap<String, HashSet<Character>> firstSetX = new HashMap<String, HashSet<Character>>();public Character S = 'E';public HashMap<Character, HashSet<Character>> followSet = new HashMap<Character, HashSet<Character>>();public HashSet<Character> VnSet = new HashSet<Character>();public HashSet<Character> VtSet = new HashSet<Character>();public HashMap<Character, ArrayList<String>> experssionSet = new HashMap<Character, ArrayList<String>>();public String[] inputExperssion = { "E->TK", "K->+TK", "K->ε", "T->FM", "M->*FM", "M->ε", "F->i", "F->(E)" };public String[][] table;public Stack<Character> analyzeStatck = new Stack<Character>();public String strInput = "i+i*i#";public String action = "";int index = 0;public void Init() {for (String e : inputExperssion) {String[] str = e.split("->");char c = str[0].charAt(0);ArrayList<String> list = experssionSet.containsKey(c) ? experssionSet.get(c) : new ArrayList<String>();list.add(str[1]);experssionSet.put(c, list);}for (Character c : VnSet)getFirst(c);for (Character c : VnSet) {ArrayList<String> l = experssionSet.get(c);for (String s : l)getFirst(s);}getFollow(S);for (Character c : VnSet) {getFollow(c);}}public void getNvNt() {for (String e : inputExperssion) {String[] str = e.split("->");VnSet.add(str[0].charAt(0));}for (String e : inputExperssion) {String[] str = e.split("->");String right = str[1];for (int i = 0; i < (); i++)if (right.charAt(i)))VtSet.add((i));}}public void getFirst(Character c) {ArrayList<String> list = experssionSet.get(c);HashSet<Character> set = firstSet.containsKey(c) ? firstSet.get(c) : new HashSet<Character>();// c为终结符直接添加if (VtSet.contains(c)) {set.add(c);firstSet.put(c, set);return;}// c为非终结符处理其每条产生式for (String s : list) {// c 推出空串直接添加if (s == Character.toString('ε')) {set.add('ε');}// X -> Y1Y2Y3… 情况else {// 从左往右扫描生成式右部int i = 0;while (i < ()) {char tn = (i);// 先处理防止未初始化getFirst(tn);HashSet<Character> tvSet = firstSet.get(tn);// 将其first集参加左部for (Character tmp : tvSet)set.add(tmp);// 假设包含空串处理下一个符号if (tvSet.contains('ε'))i++;// 否那么退出处理下一个产生式elsebreak;}}}firstSet.put(c, set);}public void getFirst(String s) {HashSet<Character> set = (firstSetX.containsKey(s)) ? firstSetX.get(s) : new HashSet<Character>();// 从左往右扫描该式int i = 0;while (i < ()) {char tn = (i);HashSet<Character> tvSet = firstSet.get(tn);// 将其非空first集参加左部for (Character tmp : tvSet)if (tmp != 'ε')set.add(tmp);// 假设包含空串处理下一个符号if (tvSet.contains('ε'))i++;// 否那么完毕elsebreak;// 到了尾部即所有符号的first集都包含空串把空串参加if (i == ()) {set.add('ε');}}firstSetX.put(s, set);}public void getFollow(char c) {ArrayList<String> list = experssionSet.get(c);HashSet<Character> setA = followSet.containsKey(c) ? followSet.get(c) : new HashSet<Character>();// 假如是开场符添加#if (c == S) {setA.add('#');}// 查找输入的所有产生式,确定c的后跟终结符for (Character ch : VnSet) {ArrayList<String> l = experssionSet.get(ch);for (String s : l)for (int i = 0; i < (); i++)if ((i) == c && i + 1 < s.length() && VtSet.contains(s.charAt(i + 1)))setA.add(s.charAt(i + 1));}followSet.put(c, setA);// 处理c的每一条产生式for (String s : list) {int i = () - 1;while (i >= 0) {char tn = (i);// 只处理非终结符if (VnSet.contains(tn)) {// 都按A->αBβ 形式处理// 假设β不存在followA 参加followB// 假设β存在,把β的非空first集参加followB// 假设β存在且first(β)包含空串followA 参加followB// 假设β存在if (() - i - 1 > 0) {String right = (i + 1);// 非空first集参加followBHashSet<Character> setF = null;if (() == 1 && firstSet.containsKey(right.charAt(0)))setF = firstSet.get((0));else {if (right)) {HashSet<Character> set = new HashSet<Character>();firstSetX.put(right, set);}setF = firstSetX.get(right);}HashSet<Character> setX = followSet.containsKey(tn) ? followSet.get(tn): new HashSet<Character>();for (Character var : setF)if (var != 'ε')setX.add(var);followSet.put(tn, setX);// 假设first(β)包含空串followA 参加followBif (setF.contains('ε')) {if (tn != c) {HashSet<Character> setB = followSet.containsKey(tn) ? followSet.get(tn): new HashSet<Character>();for (Character var : setA)setB.add(var);followSet.put(tn, setB);}}}// 假设β不存在followA 参加followBelse {// A和B一样不添加if (tn != c) {HashSet<Character> setB = followSet.containsKey(tn) ? followSet.get(tn): new HashSet<Character>();for (Character var : setA)setB.add(var);followSet.put(tn, setB);}}i--;}// 假如是终结符往前看如A->aaaBCDaaaa 此时β为CDaaaaelsei--;}}}public void createTable() {Object[] VtArray = VtSet.toArray();Object[] VnArray = VnSet.toArray();// 预测分析表初始化table = new String[VnArray.length + 1][VtArray.length + 1];table[0][0] = "Vn/Vt";// 初始化首行首列for (int i = 0; i < VtArray.length; i++)table[0][i + 1] = (VtArray[i].toString().charAt(0) == 'ε') ? "#" : VtArray[i].toString();for (int i = 0; i < VnArray.length; i++)table[i + 1][0] = VnArray[i] + "";// 全部置errorfor (int i = 0; i < VnArray.length; i++)for (int j = 0; j < VtArray.length; j++)table[i + 1][j + 1] = "error";// 插入生成式for (char A : VnSet) {ArrayList<String> l = experssionSet.get(A);for (String s : l) {HashSet<Character> set = firstSetX.get(s);for (char a : set)insert(A, a, s);if (('ε')) {HashSet<Character> setFollow = followSet.get(A);if (setFollow.contains('#'))insert(A, '#', s);for (char b : setFollow)insert(A, b, s);}}}}public void analyzeLL() {System.out.println(" Stack Input Action");analyzeStatck.push('#');analyzeStatck.push('E');displayLL();char X = analyzeStatck.peek();while (X != '#') {char a = strInput.charAt(index);if (X == a) {action = "匹配" + analyzeStatck.peek();analyzeStatck.pop();index++;} else if (VtSet.contains(X))return;else if (find(X, a).equals("error"))return;else if (find(X, a).equals("ε")) {analyzeStatck.pop();action = X + "->ε";} else {String str = find(X, a);if (str != "") {action = X + "->" + str;analyzeStatck.pop();int len = ();for (int i = len - 1; i >= 0; i--)analyzeStatck.push((i));} else {System.out.println("error at '" + strInput.charAt(index) + " in " + index);return;}}X = analyzeStatck.peek();displayLL();}System.out.println("Successful,为LL(1)文法");}public String find(char X, char a) {for (int i = 0; i < VnSet.size() + 1; i++) {if (table[i][0].charAt(0) == X)for (int j = 0; j < VtSet.size() + 1; j++) {if (table[0][j].charAt(0) == a)return table[i][j];}}return "";}public void insert(char X, char a, String s) {if (a == 'ε')a = '#';for (int i = 0; i < VnSet.size() + 1; i++) {if (table[i][0].charAt(0) == X)for (int j = 0; j < VtSet.size() + 1; j++) {if (table[0][j].charAt(0) == a) {table[i][j] = s;return;}}}}public void displayLL() {Stack<Character> s = analyzeStatck;System.out.printf("%23s", s);System.out.printf("%13s", strInput.substring(index));System.out.printf("%10s", action);System.out.println();}}public class Test {public static void main(String[] args) {LL_1 l = new LL_1();l.getNvNt();l.Init();l.createTable();l.analyzeLL();}}。

(完整)编译原理实验报告(词法分析器 语法分析器)

(完整)编译原理实验报告(词法分析器 语法分析器)

编译原理实验报告实验一一、实验名称:词法分析器的设计二、实验目的:1,词法分析器能够识别简单语言的单词符号2,识别出并输出简单语言的基本字。

标示符。

无符号整数.运算符.和界符。

三、实验要求:给出一个简单语言单词符号的种别编码词法分析器四、实验原理:1、词法分析程序的算法思想算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号.2、程序流程图(1)主程序(2)扫描子程序3、各种单词符号对应的种别码五、实验内容:1、实验分析编写程序时,先定义几个全局变量a[]、token[](均为字符串数组),c,s( char型),i,j,k(int型),a[]用来存放输入的字符串,token[]另一个则用来帮助识别单词符号,s用来表示正在分析的字符.字符串输入之后,逐个分析输入字符,判断其是否‘#’,若是表示字符串输入分析完毕,结束分析程序,若否则通过int digit(char c)、int letter(char c)判断其是数字,字符还是算术符,分别为用以判断数字或字符的情况,算术符的判断可以在switch语句中进行,还要通过函数int lookup(char token[])来判断标识符和保留字。

2 实验词法分析器源程序:#include 〈stdio.h〉#include <math.h>#include <string。

h>int i,j,k;char c,s,a[20],token[20]={’0’};int letter(char s){if((s〉=97)&&(s〈=122)) return(1);else return(0);}int digit(char s){if((s〉=48)&&(s<=57)) return(1);else return(0);}void get(){s=a[i];i=i+1;}void retract(){i=i-1;}int lookup(char token[20]){if(strcmp(token,"while")==0) return(1);else if(strcmp(token,"if")==0) return(2);else if(strcmp(token,"else”)==0) return(3);else if(strcmp(token,"switch”)==0) return(4);else if(strcmp(token,"case")==0) return(5);else return(0);}void main(){printf(”please input string :\n");i=0;do{i=i+1;scanf("%c",&a[i]);}while(a[i]!=’#’);i=1;j=0;get();while(s!=’#'){ memset(token,0,20);switch(s){case 'a':case ’b':case ’c':case ’d':case ’e’:case ’f’:case 'g’:case ’h':case 'i':case ’j':case 'k’:case ’l':case 'm’:case 'n':case ’o':case ’p':case ’q’:case 'r’:case 's’:case 't’:case ’u’:case ’v’:case ’w’:case ’x':case ’y':case ’z’:while(letter(s)||digit(s)){token[j]=s;j=j+1;get();}retract();k=lookup(token);if(k==0)printf("(%d,%s)”,6,token);else printf("(%d,—)",k);break;case ’0':case ’1’:case ’2':case ’3':case '4’:case '5’:case ’6':case ’7’:case ’8’:case '9’:while(digit(s)){token[j]=s;j=j+1;get();}retract();printf(”%d,%s",7,token);break;case '+':printf(”(’+',NULL)”);break;case ’-':printf("(’-',null)");break;case ’*':printf(”('*’,null)");break;case '<':get();if(s=='=’) printf(”(relop,LE)”);else{retract();printf("(relop,LT)");}break;case ’=':get();if(s=='=’)printf("(relop,EQ)");else{retract();printf(”('=',null)”);}break;case ’;':printf(”(;,null)");break;case ' ’:break;default:printf("!\n”);}j=0;get();} }六:实验结果:实验二一、实验名称:语法分析器的设计二、实验目的:用C语言编写对一个算术表达式实现语法分析的语法分析程序,并以四元式的形式输出,以加深对语法语义分析原理的理解,掌握语法分析程序的实现方法和技术.三、实验原理:1、算术表达式语法分析程序的算法思想首先通过关系图法构造出终结符间的左右优先函数f(a),g(a)。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

public class Accept2 {public static StringBuffer stack=new StringBuffer("#E");public static StringBuffer stack2=new StringBuffer("i+i*#");public static void main(String arts[]){//stack2.deleteCharAt(0);System.out.print(accept(stack,stack2));}public static boolean accept(StringBuffer stack,StringBuffer stack2){//判断识别与否boolean result=true;outer:while (true) {System.out.format("%-9s",stack+"");System.out.format("%9s",stack2+"\n");char c1 = stack.charAt(stack.length() - 1);char c2 = stack2.charAt(0);if(c1=='#'&&c2=='#')return true;switch (c1) {case'E':if(!E(c2)) {result=false;break outer;}break;case'P': //P代表E’if(!P(c2)) {result=false;break outer;}break;case'T':if(!T(c2)) {result=false;break outer;}break;case'Q': //Q代表T’if(!Q(c2)) {result=false;break outer;}break;case'F':if(!F(c2)) {result=false;break outer;}break;default: {//终结符的时候if(c2==c1){stack.deleteCharAt(stack.length()-1);stack2.deleteCharAt(0);//System.out.println();}else{return false;}}}if(result=false)break outer;}return result;}public static boolean E(char c) {//语法分析子程序 Eboolean result=true;if(c=='i') {stack.deleteCharAt(stack.length()-1);stack.append("PT");}else if(c=='('){stack.deleteCharAt(stack.length()-1);stack.append("PT");else{System.err.println("E 推导时错误!不能匹配!");result=false;}return result;}public static boolean P(char c){//语法分析子程序 Pboolean result=true;if(c=='+') {stack.deleteCharAt(stack.length()-1);stack.append("PT+");}else if(c==')') {stack.deleteCharAt(stack.length()-1);//stack.append("");System.out.println("P->/");}else if(c=='#') {stack.deleteCharAt(stack.length()-1);//stack.append("");System.out.println("P->/");else{System.err.println("P 推导时错误!不能匹配!");result=false;}return result;}public static boolean T(char c) {//语法分析子程序 Tboolean result=true;if(c=='i') {stack.deleteCharAt(stack.length()-1);stack.append("QF");}else if(c=='(') {stack.deleteCharAt(stack.length()-1);stack.append("QF");}else{result=false;System.err.println("T 推导时错误!不能匹配!");}return result;public static boolean Q(char c){//语法分析子程序 Q boolean result=true;if(c=='+') {stack.deleteCharAt(stack.length()-1);//stack.append("");System.out.println("Q->/");}else if(c=='*') {stack.deleteCharAt(stack.length()-1);stack.append("QF*");}else if(c==')') {stack.deleteCharAt(stack.length()-1);//stack.append("");System.out.println("Q->/");}else if(c=='#') {stack.deleteCharAt(stack.length()-1);//stack.append("");System.out.println("Q->/");}else{result=false;System.err.println("Q 推导时错误!不能匹配!");}return result;}public static boolean F(char c) {//语法分析子程序 Fboolean result=true;if(c=='i') {stack.deleteCharAt(stack.length()-1);stack.append("i");}else if(c=='(') {stack.deleteCharAt(stack.length()-1);stack.append(")E(");}else{result=false;System.err.println("F 推导时错误!不能匹配!");}return result;}/* public static StringBuffer changeOrder(String s){//左右交换顺序StringBuffer sb=new StringBuffer();for(int i=0;i<s.length();i++){sb.append(s.charAt(s.length()-1-i));}return sb;}*/}#E i+i*i+i##PT i+i*i+i##PQF i+i*i+i##PQi i+i*i+i##PQ +i*i+i#Q->/#P +i*i+i##PT+ +i*i+i##PT i*i+i##PQF i*i+i##PQi i*i+i##PQ *i+i##PQF* *i+i##PQF i+i##PQi i+i##PQ +i#Q->/#P +i##PT+ +i##PT i##PQF i##PQi i##PQ #Q->/#P #P->/# #True#E i+i*##PT i+i*##PQF i+i*##PQi i+i*##PQ +i*#Q->/#P +i*##PT+ +i*##PT i*##PQF i*##PQi i*##PQ *##PQF* *##PQF #falseF 推导时错误!不能匹配!。

相关文档
最新文档