编译原理 SysY语言的词法分析程序

Posted Ice丨shine

tags:

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

  1. 实验目的与内容
    对SysY语言进行词法分析,可以查出语言中可能包含的词法错误。
    从控制台输入字符串,如有出错则输出错误,没有错误则按照二元组的方式输出
  2. 设计方法
    对SysY语法进行分析如下:
    (1) 保留字: if else for while do continue return break int const main void
      注意:所有关键词都是小写的。
    (2) 标识符ID,与标准C语言一致,即:以下划线或字母开头的字母数字下划线组成的符号串。
    (3)运算符和分界符: +、-、*、/、% 、==、!=、<、>、<=、>= 、!、&&、|| 、(、)、、、[、]。
    (4) 空白符包括空格、制表符和换行符,用于分割标识符、保留字、运算符和分界符,词法分析阶段要忽略空白符。
    本程序使用Java编写
    程序启动输入后,字符串保留在instr中。先对字符串进行预处理,去除两个词之间多余的空格,再按空格进行切割。切割完成后逐个单词进行判断,分别判断是否属于保留字、数字、运算符和分界符等等,如果匹配成功则输出。每次判断时使用token逐个读取字符串的各个字符直到一个单词结束并且进行判断。
package cn.hdu;

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class Word //1.词法分析程序


    public static boolean IsLetter(char ch)
        if ((ch >= 'a'&&ch <= 'z') || (ch >= 'A'&&ch <= 'Z'))
            return true;
        return false;
    

    //判断是否为数字
    public static boolean IsDigit(char ch)
    
        if (ch >= '0'&&ch <= '9')
            return true;
        return false;
    

    //判断是否为分界符
    public static int IsSymbol(char ch)
    
        char symbol[]=  '(',')',',',';','<','>','','','[',']';
        for (int i = 0; i < 8; i++)
        
            if (ch == symbol[i])
                return i;
        
        return -1;
    

    //判断是否为关键字
    public static int IsKeyword(String str)
    
        String keyword[] = "if","else","for","while","do", "continue", "return", "break" ,"int", "const", "main", "void" ;
        for (int i = 0; i < keyword.length; i++)
        
            if (str.equals(keyword[i]) )
            
                return i;
            
        
        //不是关键字即为标识符
        return 30;
    


    public static boolean IsRight(String str)
    
        char[] chars = str.toCharArray();
       // System.out.println(chars.length);
        int f = 0;
        //for (int i = 0; i < str.length()-1; i++)
        //
           /* if (IsLetter(chars[i]) ||"_".equals( chars[i]))
                f=1;*/
                if (IsDigit(chars[0]))
                if (IsLetter(chars[1]) || chars[1] == '_')
                return false;
        //
       /* if(f==0) return true;
        if(!(IsLetter(chars[0])||chars[0]=='_')) return false;
        for (int i = 0; i < str.length(); i++)
        
            if (!(IsDigit(chars[i])||IsLetter(chars[i]) ||"_".equals( chars[i])))
                    return false;
        */
        return true;
    
    //多余空格处理
     public static String HandleSpace(String str)
    
        int j = 0;
        char[] word=new char[255];
        boolean temp = false;
        char[] a = str.toCharArray();
        for (int i = 0; i < a.length; i++)
        

            if (a[i] != ' ' && a[i] != '\\t')
            
                word[j++] = a[i];
                temp = false;
            
            else
            

                if (!temp&&a[i] != '\\t')
                
                    word[j++] = a[i];
                    temp = true;
                

            

        
        char[] ans = new char[j];
        for (int i = 0; i < j; i++) 
            ans[i]=word[i];
        
         return String.valueOf(ans);
    
   public static void main(String[] args) 
        String token= new String();//存放字符串
        String[] str;
       String instr;
       boolean flag=false;
        int k=0;
       Map<Integer,String> identifiers= new HashMap<>();
        Scanner sc = new Scanner(System.in);
        while(sc.hasNextLine())
            instr = sc.nextLine();
            if(instr.equals("")) break;
            str = HandleSpace(instr).split(" ");//处理多余空格后按空格分隔
            for (int j = 0; j < str.length; j++) 
                //System.out.println(i+str[i]);
                char[] strtemp = str[j].toCharArray();//将分隔好的字符串装换为字符数组
                if (!IsRight(str[j]))
                
                    System.out.println(str[j]+" 为非法输入");
                    break;
                
                for (int i = 0; i<strtemp.length&&strtemp[i]!=' '; i++) 

                    //标识符,关键词
                    if ((IsLetter((strtemp[i])) || (strtemp[i]) == '_') && !flag)
                    
                        while (i<strtemp.length&&(IsLetter(strtemp[i]) || IsDigit(strtemp[i]) || strtemp[i] == '_'))
                        
                            //System.out.println("strtemp:"+strtemp[i]);
                            token += strtemp[i];
                            i++;
                        
                        i--;
                        //System.out.println("token"+token);
                        //System.out.println("istoken"+IsKeyword(token));
                        if (IsKeyword(token) != 30)
                        
                            System.out.println("(<保留字>"+token+")");

                        

                        else

                            if(identifiers.containsKey(token))
                                System.out.println("(<标识符>,"+token+")");
                            else
                                identifiers.put(k,token);
                                System.out.println("(<标识符>,"+token+")");
                                k++;
                            
                        
                        token = "";
                    
                    else if (IsDigit(strtemp[i]) && !flag)
                    
                        while (i<strtemp.length&&IsDigit(strtemp[i]))
                        
                            token +=strtemp[i];
                            i++;
                        
                        i--;
                        System.out.println("(<数字> "+token+")");

                        token = "";
                    

                    //<,<=,<>
                    else if (strtemp[i] == '<' && !flag)
                    
                        if (i+1<strtemp.length&&strtemp[i+1] == '=')
                        
                            System.out.println("(<运算符> <=)");

                        
                        else if (i+1<strtemp.length&&strtemp[i+1] == '>')
                        
                            System.out.println("(<运算符> <>)");

                        
                        else
                        
                            System.out.println("(<运算符> < )");

                        
                    
                    //>,>=
                    else if (strtemp[i] == '>' && !flag)
                    
                        if (i+1<strtemp.length&&strtemp[i+1] == '=')
                        
                            System.out.println("(<运算符> >=)");
                            i++;
                        
                        else
                        
                            System.out.println("(<运算符> >)");

                        
                    
                    //!,!=
                    else  if (strtemp[i] == '!' && !flag)
                    
                        if (i+1<strtemp.length&&strtemp[i+1] == '=')
                        
                            System.out.println("(<运算符> !=)");

                            i++;
                        
                        else
                        
                            System.out.println("(<运算符> !)");

                        
                    
                    //+,++
                    else if (strtemp[i] == '+' && !flag)
                    
                        if (i+1<strtemp.length&&strtemp[i+1] == '+')
                        
                            System.out.println("(<运算符> ++)");
                            i++;
                        
                        else
                        
                            System.out.println("(<运算符> +)");

                        
                    
                    //-,--
                    else if (strtemp[i] == '-' && !flag)
                    
                        if (i+1<strtemp.length&&strtemp[i+1] == '-')
                        
                            System.out.println("(<运算符> --)");
                            i++;
                        
                        else
                        
                            System.out.println("(<运算符> -)");

                        
                    
                    else if (strtemp[i] == '*' && !flag)
                    
                        System.out.println("(<运算符> * )");

                    

                    else if (strtemp[i] == '/' && !flag)
                    
                        System.out.println("(<运算符> / )");


                    
                    //=,==
                    else if (strtemp[i] == '=' && !flag)
                    
                        if (i+1<strtemp.length&&strtemp[i+1] == '=')
                        
                            System.out.println("(<运算符> ==)");
                            i++;
                        
                        else
                        
                            System.out.println("(<运算符> =)");

                        


                    
                    //余下定界符等
                    else if (IsSymbol(strtemp[i]) != -1 && !flag)
                    
                        System.out.println("(<分界符> "+strtemp[i]+")");

                    
                    else if(!flag)
                    
                        System.out.println(str[j]+"为非法标识符");
                        break;
                    
                

            



        


    


  1. 程序测试
    1.输入:
    int main()
    return 0;

    输出:
    (<保留字>int)
    (<保留字>main)
    (<分界符> ()
    (<分界符> ))
    (<分界符> )
    (<保留字>return)
    (<数字> 0)
    (<分界符> 😉
    (<分界符> )
    2.输入:
    int a;
    int main()
    a=10;
    return 0;

    输出:
    (<保留字>int)
    (<标识符>,a)
    (<分界符> 😉
    (<保留字>int)
    (<保留字>main)
    (<分界符> ()
    (<分界符> ))
    (<分界符> )
    (<标识符>,a)
    (<运算符> =)
    (<数字> 10)
    (<分界符> 😉
    (<保留字>return)
    (<数字> 0)
    (<分界符> 😉
    (<分界符> )
    3.输入:
    int main()
    int 4a;

    输出:
    (<保留字>int)
    (<保留字>main)
    (<分界符> ()
    (<分界符> ))
    (<分界符> )
    (<保留字>int)
    4a; 为非法输入
    (<分界符> )
    4.输入:
    int ifElse()
    int a;
    a = 5;
    if (a == 5)
    a = 25;
    else
    a = a * 2;

    return (a);

    4.int main()
    return (ifElse());

    输出:
    (<保留字>int)
    (<标识符>,ifElse)
    (<分界符> ()
    (<分界符> ))
    (<分界符> )
    (<保留字>int)
    (<标识符>,a)
    (<分界符>;)
    (<标识符>,a)
    (<运算符> =)
    (<数字> 5)
    (<分界符>;)
    (<保留字>if)
    (<分界符> ()
    (<标识符>,a)
    (<运算符> ==)
    (<数字> 5)
    (<分界符> ))
    (<分界符> )
    (<标识符>,a)
    (<运算符> =)
    (<数字> 25)
    (<分界符>;)
    (<标识符>,a)
    (<运算符> =)
    (<数字> 25)
    (<分界符>;)
    (<分界符> )
    (<保留字>else)
    (<分界符> )
    (<标识符>,a)
    (<运算符> =)
    (<标识符>,a)
    (<运算符> * )
    (<数字> 2)
    (<分界符>;)
    (<分界符> )
    (<保留字>return)
    (<分界符> ()
    (<标识符>,a)
    (<分界符> ))
    (<分界符>;)
    (<分界符> )
    (<保留字>int)
    (<保留字>main)
    (<分界符> ()
    (<分界符> ))
    (<分界符> )
    (<保留字>return)
    (<分界符> ()
    (<标识符>,ifElse)
    (<分界符> ()
    (<分界符> ))
    (<分界符> ))
    (<分界符>;)
    (<分界符> )

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

编译原理 SysY语言的词法分析程序

编译原理课程设计词法分析程序设计

编译原理 实验一 java语言实现对C语言词法分析

编译原理 实验一 java语言实现对C语言词法分析

[编译原理]词法分析器的分析与实现

递归下降语法分析实验和词法分析实验报告,是编译原理的,做好直接发我邮箱 516786727@qq.com