编译原理 递归下降子程序的语法分析技术

Posted Ice丨shine

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了编译原理 递归下降子程序的语法分析技术相关的知识,希望对你有一定的参考价值。

  1. 实验目的与内容
    给定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个以上的测试用例(尽可能完全,包括正确和出错情况),给出测试结果。
  2. 设计方法
    给出语法分析表:

设置ans作为输出字符串,每次分析后加入ans,最后输出至txt
设置index记录当前分析到的字符串位置
flag为错误标识,一旦进入过error()则标记flag.
为每一个非终结符号建立函数进行递归。以E为例,对照分析表建立函数
在主函数中从开始符号进行分析。

  1. 函数定义
    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. 程序测试
测试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'::ε

语法分析完成
当前语句不合法

以上是关于编译原理 递归下降子程序的语法分析技术的主要内容,如果未能解决你的问题,请参考以下文章

编译原理 递归下降子程序的语法分析技术

编译原理 递归下降子程序的语法分析技术

编译原理:实验二 递归下降语法分析

编译原理-2词法分析

编译原理-2词法分析

编译原理笔记 2