编译原理 递归下降子程序的语法分析技术
Posted Ice丨shine
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了编译原理 递归下降子程序的语法分析技术相关的知识,希望对你有一定的参考价值。
- 实验目的与内容
给定SysY语言中简单算术表达式文法G[E]:
E→TE’
E’→ATE’|ε
T→FT’
T’→MFT’ |ε
F→(E) | i
A → + | -
M → * | /
根据该文法,编写递归下降分析子程序。
【说明】
终结符号i为用户定义的简单变量,即专题1中标识符的定义
1.输入:是词法分析输出的二元组序列,即任意简单算术表达式经过专题1程序输出后得到的结果。【上述文法中i即对应词法分析的标识符, ±*/分别对应词法分析得到的运算符】
2.输出:判定输入串是否为该文法定义的合法算术表达式
3.处理:程序应能发现输入串的错误
4.设计5个以上的测试用例(尽可能完全,包括正确和出错情况),给出测试结果。 - 设计方法
给出语法分析表:
设置ans作为输出字符串,每次分析后加入ans,最后输出至txt
设置index记录当前分析到的字符串位置
flag为错误标识,一旦进入过error()则标记flag.
为每一个非终结符号建立函数进行递归。以E为例,对照分析表建立函数
在主函数中从开始符号进行分析。
- 函数定义
public static String txt2String(File file);//读取文件
public static void E(char t);//对E的分析
public static void T(char t);//对T的分析
public static void Ep(char t);//对E’的分析
public static void Tp(char t);//对T’的分析
public static void F(char t);//对F的分析
public static void A(char t);//对A的分析
public static void M(char t)//对M的分析
public static void error()//对error的判断
import java.io.*;
public class Diguixiajiang {//递归下降
static String ans="";
static int index = 0; //遍历字符串的当前位置
static String str="";
static int flag=0;
public static String txt2String(File file){
try{
BufferedReader br = new BufferedReader(new FileReader(file));//构造一个BufferedReader类来读取文16
String s = null;
while((s = br.readLine())!=null){//使用readLine方法,一次读一行
str = str +s;
}
br.close();
}catch(Exception e){
e.printStackTrace();
}
return str;
}
public static void E(char t)
{
if (t == '(') {
System.out.println("E::TE'");
ans=ans+"E::TE'\\n";
T(str.charAt(index));
Ep(str.charAt(index));
}
else if (t == 'i') {
System.out.println("E::TE'");
ans=ans+"E::TE'\\n";
T(str.charAt(index));
Ep(str.charAt(index));
}
else {
error();
index++;
E(str.charAt(index));
}
}
public static void T(char t)
{
if (t == 'i') {
System.out.println("T::FT'");
ans=ans+"T::FT'"+"\\n";
F(str.charAt(index));
Tp(str.charAt(index));
}
else if (t == '(') {
System.out.println("T::FT'");
ans=ans+"T::FT'"+"\\n";
F(str.charAt(index));
Tp(str.charAt(index));
}
else
{
error();
index++;
T(str.charAt(index));
}
}
public static void Ep(char t)
{
if (t==')')
{
System.out.println("E'::ε");
ans=ans+"E'::ε"+"\\n";
index++;
}
else if (t == '+')
{
System.out.println("E'::ATE'");
ans=ans+"E'::ATE'"+"\\n";
A(str.charAt(index));
T(str.charAt(index));
Ep(str.charAt(index));
}
else if (t == '-')
{
System.out.println("E'::ATE'");
ans=ans+"E'::ATE'"+"\\n";
A(str.charAt(index));
T(str.charAt(index));
Ep(str.charAt(index));
}
else if (t=='$')
{
System.out.println("E'::ε");
ans=ans+"E'::ε"+"\\n";
}
else
{
error();
index++;
Ep(str.charAt(index));
}
}
public static void Tp(char t)
{
if (t == ')')
{
System.out.println("T'::ε");
ans=ans+"T'::ε"+"\\n";
}
else if (t == '+')
{
System.out.println("T'::ε");
ans=ans+"T'::ε"+"\\n";
}
else if (t == '-')
{
System.out.println("T'::ε");
ans=ans+"T'::ε"+"\\n";
}
else if (t == '*')
{
System.out.println("T'::MFT'");
ans=ans+"T'::MFT'"+"\\n";
M(str.charAt(index));
F(str.charAt(index));
Tp(str.charAt(index));
}
else if (t == '/')
{
System.out.println("T'::MFT'");
ans=ans+"T'::MFT'"+"\\n";
M(str.charAt(index));
F(str.charAt(index));
Tp(str.charAt(index));
}
else if (t == '$')
{
System.out.println("T'::ε");
ans=ans+"T'::ε"+"\\n";
}
else
{
error();
index++;
Tp(str.charAt(index));
}
}
public static void F(char t) {
if (t == 'i') {
System.out.println("F::i");
ans=ans+"F::i"+"\\n";
index++;
}
else if (t == '(') {
System.out.println("F->(E)");
ans=ans+"F->(E)"+"\\n";
index++;
E(str.charAt(index));
}
else {
error();
index++;
F(str.charAt(index));
}
}
public static void A(char t)
{
if (t == '+')
{
System.out.println("A::+");
ans=ans+"A::+"+"\\n";
index++;
}
else if (t == '-')
{
System.out.println("A::-");
ans=ans+"A::-"+"\\n";
index++;
}
else
{
error();
index++;
A(str.charAt(index));
}
}
public static void M(char t)
{
if(t == '*')
{
System.out.println("M::*");
ans=ans+"M::*"+"\\n";
index++;
}
else if (t == '/')
{
System.out.println("M::/");
ans=ans+"M::/"+"\\n";
index++;
}
else
{
error();
index++;
M(str.charAt(index));
}
}
public static void error()
{
System.out.println( "有一个错误,略过当前词法记号");
flag=1;
}
public static void main(String[] args){
File file = new File("diguiin.txt");
File file2 = new File("diguiout.txt");
str = txt2String(file);
System.out.println(str);
//System.out.println(str.charAt(1));
E(str.charAt(index));
System.out.println("\\n语法分析完成");
if(flag==1)
System.out.println("当前语句不合法");
else
System.out.println("当前语句合法");
try {
BufferedWriter bw = new BufferedWriter(new FileWriter(file2));
bw.write(ans);
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
- 程序测试
测试1:(i-i)*i-i/i$
输出:E::TE'
T::FT'
F->(E)
E::TE'
T::FT'
F::i
T'::ε
E'::ATE'
A::-
T::FT'
F::i
T'::ε
E'::ε
T'::ε
E'::ε
测试2:i+i/i$
输出:
E::TE'
T::FT'
F::i
T'::ε
E'::ATE'
A::+
T::FT'
F::i
T'::MFT'
M::/
F::i
T'::ε
E'::ε
测试3:i+i/i++i$
输出:
E::TE'
T::FT'
F::i
T'::ε
E'::ATE'
A::+
T::FT'
F::i
T'::MFT'
M::/
F::i
T'::ε
E'::ATE'
A::+
有一个错误,略过当前词法记号
T::FT'
F::i
T'::ε
E'::ε
语法分析完成
当前语句不合法
测试4:()i+i-i*i$
输出:
E::TE'
T::FT'
F->(E)
有一个错误,略过当前词法记号
E::TE'
T::FT'
F::i
T'::ε
E'::ATE'
A::+
T::FT'
F::i
T'::ε
E'::ATE'
A::-
T::FT'
F::i
T'::MFT'
M::*
F::i
T'::ε
E'::ε
T'::ε
E'::ε
语法分析完成
当前语句不合法
测试5:(i)//i+i-i*i$
输出:
E::TE'
T::FT'
F->(E)
E::TE'
T::FT'
F::i
T'::ε
E'::ε
T'::MFT'
M::/
有一个错误,略过当前词法记号
F::i
T'::ε
E'::ATE'
A::+
T::FT'
F::i
T'::ε
E'::ATE'
A::-
T::FT'
F::i
T'::MFT'
M::*
F::i
T'::ε
E'::ε
语法分析完成
当前语句不合法
以上是关于编译原理 递归下降子程序的语法分析技术的主要内容,如果未能解决你的问题,请参考以下文章