文档库 最新最全的文档下载
当前位置:文档库 › LL1语法分析器

LL1语法分析器

LL1语法分析器
LL1语法分析器

LL(1)分析法

一、实验目的

通过完成预测分析法的语法分析程序,了解预测分析法和递归子程序法的区别和联系。使学生了解语法分析的功能,掌握语法分析程序设计的原理和构造方法,训练学生掌握开发应用程序的基本方法。有利于提高学生的专业素质,为培养适应社会多方面需要的能力。

二、实验内容

1. 根据某一文法编制调试 LL ( 1 )分析程序,以便对任意输入的符号串进行

分析。

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

序。

3.分析法的功能是利用LL(1)控制程序根据显示栈栈顶内容、向前看符号以

及LL(1)分析表,对输入符号串自上而下的分析过程。

三、 LL(1)分析法实验设计思想及算法

模块结构:

(1)定义部分:定义常量、变量、数据结构。

(2)初始化:设立LL(1)分析表、初始化变量空间(包括堆栈、结构体、数组、临时变量等);

(3)控制部分:从键盘输入一个表达式符号串;

(4)利用LL(1)分析算法进行表达式处理:根据LL(1)分析表对表达式符号串进行堆栈(或其他)操作,输出分析结果,如果遇到错误则显示错误信息。

四、实验要求

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

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

3、对下列文法,用LL(1)分析法对任意输入的符号串进行分析:

①S→E

②E→TA

③A→+TA

④A→#

⑤T→FB

⑥B→*FB

⑦B→#

⑧F→(E)

⑨F→i

五、实验源程序

package实验;

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;//储存Vt

Object 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(new JScrollPane(table));

add(p2,"Center");

add(p3,"South");

b0.addActionListener(this);

b1.addActionListener(this);

b2.addActionListener(this);

b3.addActionListener(this);

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

table.setPreferredScrollableViewportSize(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;i

{

if(s.length<2){

t3.setText("文法输入有误,请重新输入");//判断长度是否符合

return;

}

if(s[i].charAt(0)<='Z'&&s[i].charAt(0)>='A'&&s[i].charAt(1)=='→')

{

for(k=0;k

{

if(Vn[k].equals(s[i].substring(0,

1))){

break;

}

}

if(Vnnum==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(int i=0;Vn[i]!=null;i++)

{

t3.append("first("+Vn[i]+")={ ");

for(int j=0;first[i][j]!='\0';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)ret urn;

followComplete[i]=1;

}

t3.append("follow集:"+"\n"); //显示FOLLOW**

for(int i=0;Vn[i]!=null;i++)

{

t3.append("follow("+Vn[i]+")={ ");

for(int j=0;follow[i][j]!='\0';j++)

{

t3.append(follow[i][j]+" , ");

}

t3.append("}"+"\n");

}

select=new char[P.size()][100];

for(int i=0;i

flag=0;

tianjiaSelect(select[i],(String)P.elementAt(i),flag);

}

t3.append("select集:"+"\n"); //显示SELECT**

for(int i=0;i

{

t3.append("select("+(String)P.elementAt(i)+")={ ");

for(int j=0;select[i][j]!='\0';j++)

{

t3.append(select[i][j]+" , ");

}

t3.append("}"+"\n");

}

for(int i=0;Vn[i]!=null;i++)//判断select交集是否为空

{

int biaozhi=0;

char save[]=new char[100];

for(int j=0;j

{

String t=(String)P.elementAt(j);

if(t.substring(0,1).equals(Vn[i]))

{

for(k=0;select[j][k]!='\0';k++)

{

if(puanduanChar(save,select[j][k]))

{

save[biaozhi]=select[j][k]; biaozhi++;

}

else//当有交集时,不为LL(1)文法

{

t3.append("不是LL(1)文法!!"+"\n");

return;

}

}

}

}

}

char Vt[]=new char[100];

int biaozhi=0;

for(int i=0;i

{

String t=(String)P.elementAt(i);

for(int j=2;j

{

if(t.charAt(j)>'Z'||t.charAt(j)<'A')

{

if(puanduanChar(Vt,t.charAt(j)))

{

Vt[biaozhi]=t.charAt(j);

biaozhi++;

}

}

}

}

if(puanduanChar(Vt,'#'))//若可推出空集,则将#加入Vt。 {

Vt[biaozhi]='#';

biaozhi++;

}

vt_tou=new String[biaozhi+1];//根据select和表达式生成预测分析表

shuju=new String[Vnnum][biaozhi+1];

String f="";

vt_tou[0]=f;

for(int i=0;i

{

vt_tou[i+1]=String.valueOf(Vt[i]);

}

for(int i=0;i

{

shuju[i][0]=Vn[i];

}

for(int i=0;i

{

String t=(String)P.elementAt(i);

int j;

for(j=0;j

{

if(Vn[j].equals(t.substring(0,1)))

{

break;

}

}

for(k=0;select[i][k]!='\0';k++)

{

int y=puanduanXulie(Vt,select[i][k]);

shuju[j][y+1]=t.substring(1);

}

}

dtm=new DefaultTableModel(shuju,vt_tou);//显示预测分析表

table.setModel(dtm);

LL=1;

}

if(e.getSource()==b3)//清空列表

{

tf1.setText("");

tf2.setText("");

t1.setText("");

t2.setText("");

t3.setText("");

Vn=null;

P=null;

firstComplete=null;

first=null;

followComplete=null;

follow=null;

select=null;

dtm=new DefaultTableModel();

table.setModel(dtm);

}

if(e.getSource()==b2)//输入字符串并预测分析

{

t3.setText("");

if(LL==1)

{

String s=t2.getText();

for(int i=0;i

{

if(s.charAt(i)=='\0')

{

t3.setText("字符串中请不要加入空格"+"\n");

return;

}

}

char zifu[]=new char[100];//剩余输入串

char fenxi[]=new char[100];//分析栈

zifu[0]='#';

fenxi[1]='S';

fenxi[0]='#';

int fzifu=1;

int ffenxi=2;

for(int i=s.length()-1;i>=0;i--)

{

zifu[fzifu]=s.charAt(i);

fzifu++;

}

int buzhou=2;

char n[]=new char[65];//存储要显示的内容

t3.append("步骤分析栈剩余输入串所用产生式或匹配"+"\n");

n[0]='1';

n[15]='#';

n[14]='S';

int u=29;

for(int i=fzifu-1;i>=0;i--)

{

n[u]=zifu[i];

u++;

}

while(!(fenxi[ffenxi-1]=='#'&&zifu[fzifu-1]=='#'))//剩余输入串不为#则分析

{

int i,j;

char t=zifu[fzifu-1];

char k=fenxi[ffenxi-1];

if(t==k)//产生式匹配

{

n[49]=k;

n[50]='匹';

n[51]='配';

t3.append(String.copyValueOf(n)+"\n");

n=new char[65];

fzifu--;

ffenxi--;

if(buzhou<10)

n[0]=(char)('0'+buzhou);//显示步骤数

else

{

n[0]=(char)('0'+buzhou/10);

n[1]=(char)('0'+buzhou%10);

}

u=14;

for(int y=ffenxi-1;y>=0;y--)//处理分析栈,出栈

{

n[u]=fenxi[y];

u++;

}

u=29;

for(int y=fzifu-1;y>=0;y--)//处理剩余字符串,消除一个字符

{

n[u]=zifu[y];

u++;

}

buzhou++;

continue;

}

for(i=0;Vn[i]!=null;i++)//搜寻所用产生式的左部

{

if(Vn[i].equals(String.valueOf(k)))break;

}

for(j=0;j

if(vt_tou[j].equals(String.valueOf(t)))break;

}

if(j>=vt_tou.length)//全部产生式都不能符合则报错

{

t3.append(String.copyValueOf(n));

t3.append("\n"+"该串不是该文法的句型"+"\n");

return;

}

Object result1=shuju[i][j];

if(result1==null)

{

t3.append(String.copyValueOf(n));

t3.append("\n"+"该串不是该文法的句型"+"\n");

return;

}

else//找到所用产生式

{

n[49]=Vn[i].charAt(0);

u=50;

String result=(String)result1;

for(int y=0;y

{

n[u]=result.charAt(y);

u++;

}

t3.append(String.copyValueOf(n)+"\n");

n=new char[65];

ffenxi--;

for(i=result.length()-1;i>0;i--)//将分析栈内非终结符换为右边表达式

{

if(result.charAt(i)!='#')

{

fenxi[ffenxi]=result.charAt(i);

ffenxi++;

}

}

}

if(buzhou<10)//显示“步骤”

n[0]=(char)('0'+buzhou);

else

{

n[0]=(char)('0'+buzhou/10);

n[1]=(char)('0'+buzhou%10);

}

u=14;

for(int y=ffenxi-1;y>=0;y--)

{

n[u]=fenxi[y];

u++;

}

u=29;

for(int y=fzifu-1;y>=0;y--)

{

n[u]=zifu[y];

u++;

}

buzhou++;

}

n=new char[65];

n[0]='1';

n[14]='#';

n[29]='#';

n[49]='分';

n[50]='析';

n[51]='成';

n[52]='功';

t3.append(String.copyValueOf(n));

t3.append("\n"+"该串是此文法的句型"+"\n");

return;

}

else

{

t3.setText("请先依次输入LL(1)文法,并点击文法判断按钮"+"\n");

return;

}

}

}

private int add_First(char a[],String b,String firstVn[],int flag) //计算FIRST**(递归)

{

if(puanduanString(firstVn,b.charAt(0))){addString(firstVn,b);} else

{

return flag;

}

for(int i=0;i

{

String t=(String)P.elementAt(i);

for(int k=2;k

{

if(t.substring(0, 1).equals(b))

{

if(t.charAt(k)>'Z'||t.charAt(k)<'A')//表达式右

端第i个不是非终结符

{

if(flag==0||puanduanChar(a,t.charAt(k))) {

if(t.charAt(k)=='#')//#时直接加入first {

if(k+1==t.length())

{

a[flag]=t.charAt(k);

flag++;

}

int flag1=0;

for(int

j=0;yn_null[j]!='\0';j++)//所求非终结符进入yn_null**

{

if(yn_null[j]==b.charAt(0))//判断能否推出空

{

flag1=1;break;

}

}

if(flag1==0)

{

int j;

for(j=0;yn_null[j]!='\0';j++) {

}

yn_null[j]=b.charAt(0);

}

continue;

}

else//终结符直接加入first**

{

a[flag]=t.charAt(k);

flag++;

break;

}

}break;

}

else//非终结符

{

if(!puanduanString(Vn,t.charAt(k)))

{

int p=firstComplete(t.charAt(k));//当该非终结符的first已经求出

if(p!=-1)

{

flag=addElementFirst(a,p,flag);//直接加入所求first

}

else

if((flag=add_First(a,String.valueOf(t.charAt(k)),firstVn,flag) )==-1)

return -1;

int flag1=0;

for(int j=0;yn_null[j]!='\0';j++)//当非终结符的first有空

{

if(yn_null[j]==t.charAt(k))

{

flag1=1;break;

}

}

if(flag1==1)//当非终结符的first能推出空 {

if(k+1==t.length()&&puanduanChar(a,'#'))//之后无符号,且所求first 无#

{

a[flag]='#';//first中加入#

flag++;

}

continue;//判断下一个字符

}

else

{

break;

}

}

else//错误

{

t3.setText("文法输入有误"+"\n");

return -1;

}

}

}

}

}

return flag;

}

private int tianjiaFollow(char a[],String b,String followVn[],int flag) //计算FOLLOW**(递归)

{

if(puanduanString(followVn,b.charAt(0))){addString(followVn,b) ;}

else

{

return flag;

}

if(b.equals("S"))//当为S时#存入follow

{

a[flag]='#';

flag++;

}

for(int i=0;i

{

String t=(String)P.elementAt(i);

for(int j=2;j

{

if(t.charAt(j)==b.charAt(0)&&j+1

if(t.charAt(j+1)!='\0')

{

if((t.charAt(j+1)>'Z'||t.charAt(j+1)<'A'))//所求为终结符

{

if(flag==0||puanduanChar(a,t.charAt(2)))//自身

{

a[flag]=t.charAt(j+1);

flag++;

}

}

else//所求为非终结符

{

int k;

for(k=0;Vn[k]!=null;k++)

{

if(Vn[k].equals(String.valueOf(t.charAt(j+1))))

{

break;//找寻下一个非终结符的Vn位置

}

}

flag=addElementFirst(a,k,flag);//把下一个非终结符first加入所求follow集

for(k=j+1;k

{

if((t.charAt(j+1)>'Z'||t.charAt(j+1)<'A'))break;

else

{

if(panduan_kong(t.charAt(k)))

{}

else

{

break;

}

}

}

if(k>=t.length())//下一个非终结符可推出空,把表达式左边非终结符的follow集加入所求follow集

{

int

p=followComplete(t.charAt(0));

if(p!=-1)

{

flag=addElementFollow(a,p,flag);

}

else

if((flag=tianjiaFollow(a,String.valueOf(t.charAt(0)),followVn, flag))==-1)

return -1;

}

}

}

else//错误

{

t3.setText("文法输入有误,请重新输入

"+"\n");

return -1;

}

}

if(t.charAt(j)==b.charAt(0)&&j+1==t.length())//下一个字符为空,把

表达式左边非终结符的follow集加入所求follow集

{

int p=followComplete(t.charAt(0));

if(p!=-1)

{

flag=addElementFollow(a,p,flag);

}

else

if((flag=tianjiaFollow(a,String.valueOf(t.charAt(0)),followVn,

flag))==-1)

return -1;

}

}

}

return flag;

}

private void tianjiaSelect(char a[],String b,int flag) //计算SELECT**

{

int i=2;

int biaozhi=0;

while(i

{

if((b.charAt(i)>'Z'||b.charAt(i)<'A')&&b.charAt(i)!='#')//是终

结符

{

a[flag]=b.charAt(i);//将这个字符加入到Select**,

结束Select**的计算

break;

}

else if(b.charAt(i)=='#')//是空

{

int j;

for(j=0;Vn[i]!=null;j++)//将表达式左侧的非终结符的follow加入select

{

if(Vn[j].equals(b.substring(0,1)))

{

break;

}

}

for(int k=0;follow[j][k]!='\0';k++)

{

if(puanduanChar(a,follow[j][k]))

{

a[flag]=follow[j][k];

flag++;

}

}

break;

}

else

if(b.charAt(i)>='A'&&b.charAt(i)<='Z'&&i+1

{

int j;

for(j=0;Vn[i]!=null;j++)

{

if(Vn[j].equals(String.valueOf(b.charAt(i))))

{

break;

}

}

for(int k=0;first[j][k]!='\0';k++)

{

if(puanduanChar(a,first[j][k]))//把表达式右侧所有非终结符的first集加入。

{

if(first[j][k]=='#')//first中存在空

{

biaozhi=1;

}

编译原理 语法分析器 (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;

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

编译技术 班级网络0802 学号3080610052姓名叶晨舟 指导老师朱玉全2011年 7 月 4 日

一、目的 编译技术是理论与实践并重的课程,而其实验课要综合运用一、二年级所学的多门课程的内容,用来完成一个小型编译程序。从而巩固和加强对词法分析、语法分析、语义分析、代码生成和报错处理等理论的认识和理解;培养学生对完整系统的独立分析和设计的能力,进一步培养学生的独立编程能力。 二、任务及要求 基本要求: 1.词法分析器产生下述小语言的单词序列 这个小语言的所有的单词符号,以及它们的种别编码和内部值如下表: 单词符号种别编码助记符内码值 DIM IF DO STOP END 标识符 常数(整)= + * ** , ( )1 2 3 4 5 6 7 8 9 10 11 12 13 14 $DIM $IF $DO $STOP $END $ID $INT $ASSIGN $PLUS $STAR $POWER $COMMA $LPAR $RPAR - - - - - - 内部字符串 标准二进形式 - - - - - - 对于这个小语言,有几点重要的限制: 首先,所有的关键字(如IF﹑WHILE等)都是“保留字”。所谓的保留字的意思是,用户不得使用它们作为自己定义的标示符。例如,下面的写法是绝对禁止的: IF(5)=x 其次,由于把关键字作为保留字,故可以把关键字作为一类特殊标示符来处理。也就是说,对于关键字不专设对应的转换图。但把它们(及其种别编码)预先安排在一张表格中(此表叫作保留字表)。当转换图识别出一个标识符时,就去查对这张表,确定它是否为一个关键字。 再次,如果关键字、标识符和常数之间没有确定的运算符或界符作间隔,则必须至少用一个空白符作间隔(此时,空白符不再是完全没有意义的了)。例如,一个条件语句应写为

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

《LL(1)分析器的构造》实验报告 一、实验名称 LL(1)分析器的构造 二、实验目的 设计、编制、调试一个LL(1)语法分析器,利用语法分析器对符号串的识别,加深对语法分析原理的理解。 三、实验内容和要求 设计并实现一个LL(1)语法分析器,实现对算术文法: G[E]:E->E+T|T T->T*F|F F->(E)|i 所定义的符号串进行识别,例如符号串i+i*i为文法所定义的句子,符号串ii+++*i+不是文法所定义的句子。 实验要求: 1、检测左递归,如果有则进行消除; 2、求解FIRST集和FOLLOW集; 3、构建LL(1)分析表; 4、构建LL分析程序,对于用户输入的句子,能够利用所构造的分析程序进行分析,并显示出分析过程。 四、主要仪器设备 硬件:微型计算机。 软件: Code blocks(也可以是其它集成开发环境)。 五、实验过程描述 1、程序主要框架 程序中编写了以下函数,各个函数实现的作用如下: void input_grammer(string *G);//输入文法G

//将文法G预处理得到产生式集合P,非终结符、终结符集合U、u, int eliminate_1(string *G,string *P,string U,string *GG);//消除文法G中所有直接左递归得到文法GG int* ifempty(string* P,string U,int k,int n);//判断各非终结符是否能推导为空 string* FIRST_X(string* P,string U,string u,int* empty,int k,int n);求所有非终结符的FIRST集 string FIRST(string U,string u,string* first,string s);//求符号串s=X1X2...Xn的FIRST集 string** create_table(string *P,string U,string u,int n,int t,int k,string* first);//构造分析表 void analyse(string **table,string U,string u,int t,string s);//分析符号串s 2、编写的源程序 #include #include #include using namespace std; void input_grammer(string *G)//输入文法G,n个非终结符 { int i=0;//计数 char ch='y'; while(ch=='y'){ cin>>G[i++]; cout<<"继续输入?(y/n)\n"; cin>>ch; } } void preprocess(string *G,string *P,string &U,string &u,int &n,int &t,int &k)//将文法G预处理产生式集合P,非终结符、终结符集合U、u, { int i,j,r,temp;//计数 char C;//记录规则中()后的符号 int flag;//检测到() n=t=k=0; for( i=0;i<50;i++) P[i]=" ";//字符串如果不初始化,在使用P[i][j]=a时将不能改变,可以用P[i].append(1,a) U=u=" ";//字符串如果不初始化,无法使用U[i]=a赋值,可以用U.append(1,a) for(n=0;!G[n].empty();n++) { U[n]=G[n][0]; }//非终结符集合,n为非终结符个数 for(i=0;i

编译原理语法分析器实验

语法分析器的设计 一、实验内容 语法分析程序用LL(1)语法分析方法。首先输入定义好的文法书写文件(所用的文法可以用LL(1)分析),先求出所输入的文法的每个非终结符是否能推出空,再分别计算非终结符号的FIRST集合,每个非终结符号的FOLLOW集合,以及每个规则的SELECT集合,并判断任意一个非终结符号的任意两个规则的SELECT 集的交集是不是都为空,如果是,则输入文法符合LL(1)文法,可以进行分析。对于文法: G[E]: E->E+T|T T->T*F|F F->i|(E) 分析句子i+i*i是否符合文法。 二、基本思想 1、语法分析器实现 语法分析是编译过程的核心部分,它的主要任务是按照程序的语法规则,从由词法分析输出的源程序符号串中识别出各类语法成分,同时进行词法检查,为语义分析和代码生成作准备。这里采用自顶向下的LL(1)分析方法。 语法分析程序的流程图如图5-4所示。 语法分析程序流程图 该程序可分为如下几步: (1)读入文法 (2)判断正误 (3)若无误,判断是否为LL(1)文法 (4)若是,构造分析表; (5)由句型判别算法判断输入符号串是为该文法的句型。 三、核心思想 该分析程序有15部分组成: (1)首先定义各种需要用到的常量和变量;

(2)判断一个字符是否在指定字符串中; (3)读入一个文法; (4)将单个符号或符号串并入另一符号串; (5)求所有能直接推出&的符号; (6)求某一符号能否推出‘& ’; (7)判断读入的文法是否正确; (8)求单个符号的FIRST; (9)求各产生式右部的FIRST; (10)求各产生式左部的FOLLOW; (11)判断读入文法是否为一个LL(1)文法; (12)构造分析表M; (13)句型判别算法; (14)一个用户调用函数; (15)主函数; 下面是其中几部分程序段的算法思想: 1、求能推出空的非终结符集 Ⅰ、实例中求直接推出空的empty集的算法描述如下: void emp(char c){ 参数c为空符号 char temp[10];定义临时数组 int i; for(i=0;i<=count-1;i++)从文法的第一个产生式开始查找 { if 产生式右部第一个符号是空符号并且右部长度为1, then将该条产生式左部符号保存在临时数组temp中 将临时数组中的元素合并到记录可推出&符号的数组empty中。 } Ⅱ、求某一符号能否推出'&' int _emp(char c) { //若能推出&,返回1;否则,返回0 int i,j,k,result=1,mark=0; char temp[20]; temp[0]=c; temp[1]='\0'; 存放到一个临时数组empt里,标识此字符已查找其是否可推出空字 如果c在可直接推出空字的empty[]中,返回1 for(i=0;;i++) { if(i==count) return(0); 找一个左部为c的产生式 j=strlen(right[i]); //j为c所在产生式右部的长度 if 右部长度为1且右部第一个字符在empty[]中. then返回1(A->B,B可推出空) if 右部长度为1但第一个字符为终结符,then 返回0(A->a,a为终结符) else

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

. 编译原理实验专业:13级网络工程

语法分析器1 一、实现方法描述 所给文法为G【E】; E->TE’ E’->+TE’|空 T->FT’ T’->*FT’|空 F->i|(E) 递归子程序法: 首先计算出五个非终结符的first集合follow集,然后根据五个产生式定义了五个函数。定义字符数组vocabulary来存储输入的句子,字符指针ch指向vocabulary。从非终结符E函数出发,如果首字符属于E的first集,则依次进入T函数和E’函数,开始递归调用。在每个函数中,都要判断指针所指字符是否属于该非终结符的first集,属于则根据产生式进入下一个函数进行调用,若first集中有空字符,还要判断是否属于该非终结符的follow集。以分号作为结束符。 二、实现代码 头文件shiyan3.h #include #include

#include using namespace std; #define num 100 char vocabulary[num]; char *ch; void judge_E(); void judge_EE(); void judge_T(); void judge_TT(); void judge_F(); 源文件 #include"shiyan3.h" void judge_E() { if(*ch==';') { cout<<"该句子符合此文法!"<

int a=0; cout<<"按1结束程序"<>a; if(a==1) exit(0); } else if(*ch=='('||*ch=='i') { judge_T(); judge_EE(); } else { cout<<"该句子不匹配此文法!"<>a; if(a==1) exit(0); }

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

编译原理程序设计实验报告 ——表达式语法分析器的设计班级:计算机1306班:涛学号:20133967 实验目标:用LL(1)分析法设计实现表达式语法分析器 实验容: ⑴概要设计:通过对实验一的此法分析器的程序稍加改造,使其能够输出正确的表达式的token序列。然后利用LL(1)分析法实现语法分析。 ⑵数据结构: int op=0; //当前判断进度 char ch; //当前字符 char nowword[10]=""; //当前单词 char operate[4]={'+','-','*','/'}; //运算符 char bound[2]={'(',')'}; //界符 struct Token { int code; char ch[10]; }; //Token定义

struct Token tokenlist[50]; //Token数组struct Token tokentemp; //临时Token变量struct Stack //分析栈定义 { char *base; char *top; int stacksize; }; ⑶分析表及流程图

逆序压栈 int IsLetter(char ch) //判断ch是否为字母 int IsDigit(char ch) //判断ch是否为数字 int Iskey(char *string) //判断是否为关键字 int Isbound(char ch) //判断是否为界符 int Isboundnum(char ch) //给出界符所在token值int init(STack *s) //栈初始化 int pop(STack *s,char *ch) //弹栈操作 int push(STack *s,char ch) //压栈操作 void LL1(); //分析函数 源程序代码:(加入注释)

词法分析器的实现与设计

题目:词法分析器的设计与实现 一、引言................................ 错误!未定义书签。 二、词法分析器的设计 (3) 2.1词的内部定义 (3) 2.2词法分析器的任务及功能 (3) 3 2.2.2 功能: (4) 2.3单词符号对应的种别码: (4) 三、词法分析器的实现 (5) 3.1主程序示意图: (5) 3.2函数定义说明 (6) 3.3程序设计实现及功能说明 (6) 错误!未定义书签。 7 7 四、词法分析程序的C语言源代码: (7) 五、结果分析: (12) 摘要:词法分析是中文信息处理中的一项基础性工作。词法分析结果的好坏将直接影响中文信息处理上层应用的效果。通过权威的评测和实际应用表明,IRLAS是一个高精度、高质量的、高可靠性的词法分析系统。众所周知,切分歧义和未登录词识别是中文分词中的两大难点。理解词法分析在编译程序中的作用,加深对有穷自动机模型的理解,掌握词法分析程序的实

现方法和技术,用c语言对一个简单语言的子集编制一个一遍扫描的编译程序,以加深对编译原理的理解,掌握编译程序的实现方法和技术。Abstract:lexical analysis is a basic task in Chinese information processing. The results of lexical analysis will directly affect the effectiveness of the application of Chinese information processing. The evaluation and practical application show that IRLAS is a high precision, high quality and high reliability lexical analysis system. It is well known that segmentation ambiguity and unknown word recognition are the two major difficulties in Chinese word segmentation. The understanding of lexical analyse the program at compile, deepen of finite automata model for understanding, master lexical analysis program implementation method and technology, using C language subset of a simple language compilation of a scanned again compiler, to deepen to compile the principle solution, master compiler implementation method and technology. 关键词:词法分析器?扫描器?单词符号?预处理 Keywords: lexical analyzer word symbol pretreatment scanner 一、引言 运用C语言设计词法分析器,由指定文件读入预分析的源程序,经过词法分析器的分析,将结果写入指定文件。本程序是在Visual?Studio环境下,使用C语言作为开发工具。基于实验任务

词法分析器实验报告

词法分析器实验报告 词法分析器设计 一、实验目的: 对C语言的一个子集设计并实现一个简单的词法分析器,掌握利用状 态转换图设计词法分析器的基本方法。利用该词法分析器完成对源程 序字符串的词法分析。输出形式是源程序的单词符号二元式的代码, 并保存到文件中。 二、实验内容: 1. 设计原理 词法分析的任务:从左至右逐个字符地对源程序进行扫描,产生一个个单词符号。 理论基础:有限自动机、正规文法、正规式 词法分析器(Lexical Analyzer) 又称扫描器(Scanner):执行词法分析的程序 2. 词法分析器的功能和输出形式 功能:输入源程序、输出单词符号 程序语言的单词符号一般分为以下五种:关键字、标识符、常数、运算符,界符 3. 输出的单词符号的表示形式: 单词种别用整数编码,关键字一字一种,标识符统归为一种,常数一种,各种符号各一种。 4. 词法分析器的结构 单词符号 5. 状态转换图实现

三、程序设计 1.总体模块设计 /*用来存储目标文件名*/ string file_name; /*提取文本文件中的信息。*/ string GetText(); /*获得一个单词符号,从位置i开始查找。并且有一个引用参数j,用来返回这个单词最后一个字符在str的位置。*/ string GetWord(string str,int i,int& j); /*这个函数用来除去字符串中连续的空格和换行 int DeleteNull(string str,int i); /*判断i当前所指的字符是否为一个分界符,是的话返回真,反之假*/ bool IsBoundary(string str,int i); /*判断i当前所指的字符是否为一个运算符,是的话返回真,反之假*/ bool IsOperation(string str,int i);

语法分析器实验报告

语法分析器的设计实验报告 一、实验内容 语法分析程序用LL(1)语法分析方法。首先输入定义好的文法书写文件(所用的文法可以用LL(1)分析),先求出所输入的文法的每个非终结符是否能推出空,再分别计算非终结符号的FIRST集合,每个非终结符号的FOLLOW集合,以及每个规则的SELECT集合,并判断任意一个非终结符号的任意两个规则的SELECT 集的交集是不是都为空,如果是,则输入文法符合LL(1)文法,可以进行分析。对于文法: G[E]: E->E+T|T T->T*F|F F->i|(E) 分析句子i+i*i是否符合文法。 二、基本思想 1、语法分析器实现 语法分析是编译过程的核心部分,它的主要任务是按照程序的语法规则,从由词法分析输出的源程序符号串中识别出各类语法成分,同时进行词法检查,为语义分析和代码生成作准备。这里采用自顶向下的LL(1)分析方法。 语法分析程序的流程图如图5-4所示。 语法分析程序流程图 该程序可分为如下几步: (1)读入文法 (2)判断正误 (3)若无误,判断是否为LL(1)文法 (4)若是,构造分析表; (5)由句型判别算法判断输入符号串是为该文法的句型。 三、核心思想 该分析程序有15部分组成: (1)首先定义各种需要用到的常量和变量;

(2)判断一个字符是否在指定字符串中; (3)读入一个文法; (4)将单个符号或符号串并入另一符号串; (5)求所有能直接推出&的符号; (6)求某一符号能否推出‘& ’; (7)判断读入的文法是否正确; (8)求单个符号的FIRST; (9)求各产生式右部的FIRST; (10)求各产生式左部的FOLLOW; (11)判断读入文法是否为一个LL(1)文法; (12)构造分析表M; (13)句型判别算法; (14)一个用户调用函数; (15)主函数; 下面是其中几部分程序段的算法思想: 1、求能推出空的非终结符集 Ⅰ、实例中求直接推出空的empty集的算法描述如下: void emp(char c){ 参数c为空符号 char temp[10];定义临时数组 int i; for(i=0;i<=count-1;i++)从文法的第一个产生式开始查找 { if 产生式右部第一个符号是空符号并且右部长度为1, then将该条产生式左部符号保存在临时数组temp中 将临时数组中的元素合并到记录可推出&符号的数组empty中。 } Ⅱ、求某一符号能否推出'&' int _emp(char c) { //若能推出&,返回1;否则,返回0 int i,j,k,result=1,mark=0; char temp[20]; temp[0]=c; temp[1]='\0'; 存放到一个临时数组empt里,标识此字符已查找其是否可推出空字 如果c在可直接推出空字的empty[]中,返回1 for(i=0;;i++) { if(i==count) return(0); 找一个左部为c的产生式 j=strlen(right[i]); //j为c所在产生式右部的长度 if 右部长度为1且右部第一个字符在empty[]中. then返回1(A->B,B可推出空) if 右部长度为1但第一个字符为终结符,then 返回0(A->a,a为终结符) else

西安邮电大学编译原理语法分析器的制作

《编译原理》实验报告题目: 语法分析器的制作 学生姓名:江荣吉 班级: 学号: 指导教师: 成绩: 西安邮电大学计算机学院 2015 年 6 月 7 日

一:实验目的 熟悉语法分析的过程; 理解相关文法的步骤; 熟悉First集和Follow集生成 二:实验要求 对于给定的文法,试编写调试一个语法分析程序: 要求和提示: (1)可选择一种你感兴趣的语法分析方法(LL(1)、算符优先、递归下降、SLR(1)等)作为编制语法分析程序的依据。 (2)对于所选定的分析方法,如有需要,应选择一种合适的数据结构,以构造所给文法的机内表示。 (3)能进行分析过程模拟。如输入一个句子,能输出与句子对应的语法树,能对语法树生成过程进行模拟;能够输出分析过程每一步符号栈的变化情 况。 设计一个由给定文法生成First集和Follow集并进行简化的算法动态模拟。 三:实验过程 1:文法: E->TE’ E’->+TE’|ε T->FT’ T’->*FT’|ε F->(E)|i: 2程序描述(LL(1)文法) 本程序是基于已构建好的某一个语法的预测分析表来对用户的输入字符串进行分析,判断输入的字符串是否属于该文法的句子。 基本实现思想:接收用户输入的字符串(字符串以“#”表示结束)后,对用做分析栈的一维数组和存放分析表的二维数组进行初始化。然后取出分析栈的栈顶字符,判断是否为终结符,若为终结符则判断是否为“#”且与当前输入符号一样,若是则语法分析结束,输入的字符串为文法的一个句子,否则出错若不为“#”且与当前输入符号一样则将栈顶符号出栈,当前输入符号从输入字符串中除去,进入下一个字符的分析。若不为“#”且不与当前输入符号一样,则出错。

词法分析器的设计与实现

目录 一.设计题目 (2) 二.设计要求 (2) 1. 词法分析器的定义 (2) 2. 设计要求 (2) 3. 本程序自行规定: (3) 三.设计作用与目的 (4) 1. 设计作用 (4) 2. 设计目的 (4) 四.运行环境及工具软件 (4) 五.系统设计 (5) 1. 系统总体设计 (5) (1)词法分析器的设计 (5) (2)总体设计框图 (6) (3)总程序流程图 (6) 2. 各子模块设计 (8) (1)字符的识别 (8) (2)关键字的识别 (8) (3)数字的识别 (8) (4)界符的识别 (10) (5)运算处理 (10) 3.相关函数分析 (11) 4. 源程序设计 (12) 六.实验调试结果 (29) 1. 调试工具 (29) 2. 调试步骤 (29) 3. 调试结果 (29) 七.设计中的问题及解决方法 (31) 八.设计心得 (32) 九.参考文献 (34)

词法分析器的设计与实现 一.设计题目 词法分析器的设计与实现 二.设计要求 1. 词法分析器的定义 词法分析顾名思义就是分词。它以程序设计语言编制的源程序作为输入,以单词序列作为输出。分词过程可以通过编制程序自动完成,我们通常称这个分词程序为词法分析器。词法分析器分析的源程序可以是现有的各类程序设计语言源程序也可以是人为给定的模型语言的源程序。本文中的源程序为后者。从词的角度来看,它涉及的内容较为简单,只包括几个较为常用的词类,词类的构成上也适当的作了一些简化。对词进行分析时,我们是按类型进行分析的。不同类型的词在后续的分析中所起的作用不同,相应的操作也各有不同,但同种类型中的词虽然单词的构成不同但从宏观上看它们的操作大体一致。模型语言中的单词可以分为“关键字”、“标识符”、“常数”、“分隔符”、“运算符”几类。一般,关键字在程序设计语言中人为给定 2. 设计要求 对给定的程序通过词法分析器能够识别一个个单词符号,并以二元式(单词种别码,单词符号的属性值)显示。而本程序则是通过对给定路径的文件的分析后以单词符号和文字提示显示。另外,如果是算术表达式,则需要通过栈、运算符的优先级比较处理等从而计算出最终结果并显示。通过此次课程设计要求掌握从源程序文件中读取有效字符的方法,掌握词法分析的实现方法并上机调试编出的词法分析程序。 在处理表达式前,首先设置两个栈:一是运算符栈,用于在表达式处理过程中存放运算符。在开始时,运算符栈中先压入一个表达式结束符“#”。二是操作数栈,用于在表达式处理过程中存放操作数。然后从左到右依次读出表达式中的各个符号(运算符或操作数),每读出一个符号按以下原则进行处理:

词法分析器实验报告

词法分析器实验报告 一、实验目的及要求 本次实验通过用C语言设计、编制、调试一个词法分析子程序,识别单词,实现一个C语言词法分析器,经过此过程可以加深对编译器解析单词流的过程的了解。 运行环境: 硬件:windows xp 软件:visual c++6.0 二、实验步骤 1.查询资料,了解词法分析器的工作过程与原理。 2.分析题目,整理出基本设计思路。 3.实践编码,将设计思想转换用c语言编码实现,编译运行。 4.测试功能,多次设置包含不同字符,关键字的待解析文件,仔细察看运行结果,检测该分析器的分析结果是否正确。通过最终的测试发现问题,逐渐完善代码中设置的分析对象与关键字表,拓宽分析范围提高分析能力。 三、实验内容 本实验中将c语言单词符号分成了四类:关键字key(特别的将main说明为主函数)、普通标示符、常数和界符。将关键字初始化在一个字符型指针数组*key[]中,将界符分别由程序中的case列出。在词法分析过程中,关键字表和case列出的界符的内容是固定不变的(由程序中的初始化确定),因此,从源文件字符串中识别出现的关键字,界符只能从其中选取。标识符、常数是在分析过程中不断形成的。 对于一个具体源程序而言,在扫描字符串时识别出一个单词,若这个单词的类型是关键字、普通标示符、常数或界符中之一,那么就将此单词以文字说明的形式输出.每次调用词法分析程序,它均能自动继续扫描下去,形成下一个单词,直到整个源程序全部扫描完毕,从而形成相应的单词串。 输出形式例如:void $关键字

流程图、程序流程图:

程序: #include #include #include #include //定义关键字 char *Key[10]={"main","void","int","char","printf","scanf","else","if","return"}; char Word[20],ch; // 存储识别出的单词流 int IsAlpha(char c) { //判断是否为字母 if(((c<='z')&&(c>='a'))||((c<='Z')&&(c>='A'))) return 1; else return 0; } int IsNum(char c){ //判断是否为数字 if(c>='0'&&c<='9') return 1; else return 0; } int IsKey(char *Word){ //识别关键字函数 int m,i; for(i=0;i<9;i++){ if((m=strcmp(Word,Key[i]))==0) { if(i==0) return 2; return 1; } } return 0; } void scanner(FILE *fp){ //扫描函数 char Word[20]={'\0'}; char ch; int i,c; ch=fgetc(fp); //获取字符,指针fp并自动指向下一个字符 if(IsAlpha(ch)){ //判断该字符是否是字母 Word[0]=ch; ch=fgetc(fp);

lR语法分析器设计

LR分析程序设计 1实验目的 (1)构造LR 分析程序,利用它进行语法分析,判断给出的符号串是否为 该文法识别的句子; (2)了解LR分析方法是严格的从左向右扫描,和自底向上的语法分析方法。 2实验内容和实验要求 (1)LR分析器能够构造来识别所有能用上下文无关文法写的程序设计语言的结构。 (2)LR分析方法是已知的最一般的无回溯,移进-归约方法,它能够和其他移进-归约方法一样有效地实现。 (3)LR方法能分析的文法类是预测分析法能分析的文法类的真超集。 3 待分析的语法描述 E->vI:T I->I,i|i T->r 4算法描述 LR分析法基本思想 LR分析法是一种能够根据分析栈中的文法符号串(状态)和向右顺序查看第k个输入字符就能够唯一确定LR(k)分析器的动作是移进还是用哪一条产生式归约的分析方法。 采用LR(0)分析法进行本次实验,即无需向前查看输入符号就能够确定分析器的动作。 实现方法 LR(0)分析器由三个部分组成: (1)总控程序,也可以称为驱动程序。对所有的LR分析器总控程序都是相同的。 (2)分析表,不同的文法分析表将不同,同一个文法采用的LR分析器不同时,分析表将不同,分析表又可以分为动作表(ACTION)和状态转换(GOTO)表两个部分,它们都可用二维数组表示。由于它是总控程序的依据,所以在程序的第一部分就已经定义好。 (3)分析栈,包括文法符号栈和相应的状态栈,它们均是先进后出栈。 分析器的动作就是由栈顶状态和当前输入符号所决定。 (4)LR分析器及时察觉语法错误,快到自左向右扫描输入的最大可能。 为了使一个文法是LR的,只要保证当句柄出现在栈顶时,自左向右扫描的移进-归约分析器能够及时识别它便足够了。当句柄出现在栈顶时,LR分析器必须要扫描整个栈就可以知道这一点,栈顶的状态符号包含了所需要的一切信息。如果仅知道栈内的文法符号就能确定栈顶是什么句柄。由于LR分析表的转移函数本

编译原理词法分析器语法分析课程设计报告书

《编译原理》 课程设计 院系信息科学与技术学院 专业软件工程 年级 2011级 学号 20112723 姓名林苾湲 西南交通大学信息科学与技术学院 2013年 12月

目录 课程设计1 词法分析器 (2) 1.1 设计题目 (2) 1.2 设计容 (2) 1.3 设计目的 (2) 1.4 设计环境 (2) 1.5 需求分析 (2) 1.6 概要设计 (2) 1.7 详细设计 (4) 1.8 编程调试 (5) 1.9 测试 (11) 1.10 结束语 (13) 课程设计2 赋值语句的解释程序设计 (14) 2.1 设计题目 (14) 2.2 设计容 (14) 2.3 设计目的 (14) 2.4 设计环境 (14) 2.5 需求分析 (15) 2.6 概要设计 (16) 2.7 详细设计 (16) 2.8 编程调试 (24) 2.9 测试 (24) 2.10 结束语 (25)

课程设计一词法分析器设计 一、设计题目 手工设计c语言的词法分析器(可以是c语言的子集)。 二、设计容 处理c语言源程序,过滤掉无用符号,判断源程序中单词的合法性,并分解出正确的单词,以二元组形式存放在文件中。 三、设计目的 了解高级语言单词的分类,了解状态图以及如何表示并识别单词规则,掌握状态图到识别程序的编程。 四、设计环境 该课程设计包括的硬件和软件条件如下: 4.1.硬件 (1)Intel Core Duo CPU P8700 (2)存4G 4.2.软件 (1)Window 7 32位操作系统 (2)Microsoft Visual Studio c#开发平台 4.3.编程语言 C#语言 五、需求分析 5.1.源程序的预处理:源程序中,存在许多编辑用的符号,他们对程序逻辑功能无任何影响。例如:回车,换行,多余空白符,注释行等。在词法分析之前,首先要先剔除掉这些符号,使得词法分析更为简单。 5.2.单词符号的识别并判断单词的合法性:将每个单词符号进行不同类别的划分。单词符号可以划分成5中。 (1)标识符:用户自己定义的名字,常量名,变量名和过程名。 (2)常数:各种类型的常数。 (3) 保留字(关键字):如if、else、while、int、float等。 (4) 运算符:如+、-、*、<、>、=等。 (5)界符:如逗号、分号、括号等。 5.3.将所有合法的单词符号转化为便于计算机处理的二元组形式:(单词分类号,单词自身值);以图形化界面显示出来。 5.4.可选择性地将结果保存到文件中。 六、概要设计 6.1.数据类型 6.1.1.单词的分类:本词法分析器演示的是C语言的一个子集,故字符集如下:

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

编译原理语法分析器实验报告 班级: 学号: 姓名:

实验名称语法分析器 一、实验目的 1、根据某一文法编制调试LL(1)分析程序,以便对任意输入的符号串进行分析。 2、本次实验的目的主要是加深对自上而下分析法的理解。 二、实验内容 [问题描述] 递归下降分析法: 0.定义部分:定义常量、变量、数据结构。 1.初始化:从文件将输入符号串输入到字符缓冲区中。 2.利用递归下降分析法分析,对每个非终结符编写函数,在主函数中调用文法开始符号的函数。 LL(1)分析法: 模块结构: 1、定义部分:定义常量、变量、数据结构。 2、初始化:设立LL(1)分析表、初始化变量空间(包括堆栈、结构体等); 3、运行程序:让程序分析一个text文件,判断输入的字符串是否符合文法定义的规则; 4、利用LL(1)分析算法进行表达式处理:根据LL(1)分析表对表达式 符号串进行堆栈(或其他)操作,输出分析结果,如果遇到错误则显示简 单的错误提示。 [基本要求] 1. 对数据输入读取 2. 格式化输出分析结果 2.简单的程序实现词法分析 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+"有词法错误!");

编译语言-语法分析器的设计

实验三语法分析器的设计 一、实验内容 设计、编写和调试构造LR(0)项目集规范簇或实现基于LR分析表对给定的符号串进行LR 分析的程序。以下两个内容任选其中一项: (1)对于给定的文法,实现构造识别该文法全部活前缀DFA的程序。 (2)对于给定的LR分析表和符号串,设计程序以实现所输入符号串是否为合法符号串。 要求用JAVA语言编程。(可参考实验指导书P149至P156) 二、程序代码 AnalysisOfGrammer.java package analysis; import javax.swing.*; import javax.swing.table.DefaultTableModel; import java.awt.*; import java.awt.event.*; import java.io.*; import java.util.LinkedList; publicclass AnalysisOfGrammer extends JApplet{ private JFileChooser jfc = new JFileChooser(new File(".")); private JButton jbt1 = new JButton("打开文法文件"); private JButton jbt2 = new JButton("构造LR规范簇"); private JButton jbt3 = new JButton("构造LR分析表"); private JButton jbt4 = new JButton("清空"); private JButton jbt5 = new JButton("退出"); private JLabel jl1 = new JLabel("LR(0)项目集规范簇"); private JLabel jl2 = new JLabel("LR(0)分析表"); private JPanel p3 = new JPanel(); private JTextArea jta1 = new JTextArea(); private String[] grammer = new String[50]; privateint count = 0; private LinkedListlist = new LinkedList(); private Object content[][] = new Object[100][4]; int num1 = 0; String[][] cache = new String[50][100]; int[] location = newint[50]; int back = 0; publicvoid clear1(){ grammer = null; } publicvoid clear2(){ num1 = 0;

相关文档
相关文档 最新文档