词法分析器

本文介绍了如何构造一个确定有限状态自动机(DFA),该DFA接受一个二进制符号串,其中每个1后面都紧跟着0。通过正规式(0|10)*进行分析,详细步骤包括NFA的构建、NFA确定化以及DFA的最小化过程。

例题:构造一个DFA,它接受一个二进制符号串:每个1都有0直接跟在右边,并将其化简。

解析:由题意可知这个符号串是由0和10构成的,所以它的正规式为:(0|10)*

(1):求NFA:

(2):NFA确定化:ԑ_I是初始集I的ԑ闭包,I_0是I集合的0弧转换的ԑ闭包,I_1同理。

ԑ_II_0I_1
{X,A,Y}{A,Y}{B}
{A,Y}{A,Y}{B}
{B}{A,Y} 

换掉其中的集合:

ԑ_II_0I_1
123
223
32 

得到DFA:

(3):DFA最小化:

初始划分:{1,2},{3};

            由于f(1,0) = {1,2},f(2,0) = {1,2},f(1,1) = {3},f{2,1} = {3}

            所以划分合理最后得到:

解题完毕。

词法分析器

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextArea;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
import java.util.HashMap;

public class LexDemo extends Application {

    private GridPane gridPane = new GridPane() ;
    private char ch ;
    private HashMap<String, Integer> imSeedCode;      //记录关键字种别码
    private char[] input = new char[255] ;          //输入字符串
    private String taken ;          //单词缓冲区
    private String put = "" ;            //输出
    private TextArea putTextArea = new TextArea() ;      //输出文本框
    private final int digitCode = 23 ;      //数字编码
    private final int signCode = 24 ;       //标识符编码

    public void seedCodeInit(){         //初始化关键字种别码
        this.imSeedCode = new HashMap<>() ;
        imSeedCode.put("BEGIN", 1) ;
        imSeedCode.put("END", 2) ;
        imSeedCode.put("VAR", 3) ;
        imSeedCode.put("INTEGER", 4) ;
        imSeedCode.put("WHILE", 5) ;
        imSeedCode.put("IF", 6) ;
        imSeedCode.put("THEN", 7) ;
        imSeedCode.put("ELSE", 8) ;
        imSeedCode.put("DO", 9) ;
        imSeedCode.put("PROCEDURE", 10) ;
        imSeedCode.put(":", 11) ;
        imSeedCode.put(";", 12) ;
        imSeedCode.put("+", 13) ;
        imSeedCode.put("*", 14) ;
        imSeedCode.put("<", 15) ;
        imSeedCode.put(">", 16) ;
        imSeedCode.put("<=", 17) ;
        imSeedCode.put(">=", 18) ;
        imSeedCode.put("<>", 19) ;
        imSeedCode.put("=", 20) ;
        imSeedCode.put("(", 21) ;
        imSeedCode.put(")", 22) ;
    }

    public void init(){         //初始化
        seedCodeInit() ;
        gridPane.setPadding(new Insets(8, 8, 8, 8));
        gridPane.setHgap(5) ;
        gridPane.setVgap(5) ;
    }

    public void conCat(){       //拼接字符串
        taken += ch ;
    }

    public boolean isLetter(){      //判断是否是大写字母
        if (ch >= 'A'&&ch <= 'Z')
            return true;
        else
            return false;
    }

    public boolean isDigit(){
        if(ch >= '0' && ch <= '9'){
            return true ;
        }
        else
            return false ;
    }

    public int reserve(){       //判断taken是否是关键字
        if(imSeedCode.get(taken) != null){
            return imSeedCode.get(taken) ;
        }
        else
            return signCode ;
    }

    @Override
    public void start(Stage stage) throws Exception {
        Scene scene ;
        BorderPane borderPane = new BorderPane() ;

        //程序输入框
        TextArea textArea = new TextArea() ;
        textArea.setEditable(true); // 设置多行输入框能否编辑
        textArea.setPromptText("请输入程序"); // 设置多行输入框的提示语
        textArea.setWrapText(true); // 设置多行输入框是否支持自动换行。true表示支持,false表示不支持。
        textArea.setStyle("-fx-min-height: 150 ;");
        borderPane.setTop(textArea) ;

        //输出框
        putTextArea.setEditable(true);
        putTextArea.setWrapText(true);
        putTextArea.setStyle("-fx-min-height: 150 ;");
        borderPane.setBottom(putTextArea);

        //按钮
        Button button = new Button("分析") ;
        button.setOnMouseClicked(e->buttonClick(textArea.getText()));     //添加事件
        borderPane.setCenter(button);

        scene = new Scene(borderPane, 500, 400) ;
        stage.setScene(scene);
        scene.getStylesheets().add("style.css");;
        stage.setTitle("词法分析器");
        stage.show();
    }

    public void buttonClick(String input){
        this.input = input.toCharArray() ;
        init() ;
        lex() ;
        put += "分析完毕" ;
        putTextArea.setText(put);
    }

    //词法扫描程序
    public void lex(){

        int i ;
        for(i=-1; i<input.length;){
            taken = "" ;
            if(i+1 >= input.length)
                break;
            else
                ch = input[++i] ;       //读取下个字符

            while(ch == ' ' || ch == 10)    //去空格
                ch = input[++i] ;

            if(isLetter()){         //判断是不是关键字
                conCat();
                if(i+1 >= input.length) {
                    System.out.println("("+taken+","+reserve()+")");
                    put += "("+taken+","+reserve()+")\n" ;
                    return;
                }
                else
                    ch = input[++i] ;       //读取下个字符
                while(isDigit() || isLetter()){
                    conCat();
                    if(i+1 >= input.length){
                        System.out.println("("+taken+","+reserve()+")");
                        put += "("+taken+","+reserve()+")\n" ;
                        return;
                    }
                    else
                        ch = input[++i] ;       //读取下个字符
                }
                    ch = input[--i] ;       //回退一个字符
                    System.out.println("("+taken+","+reserve()+")");
                put += "("+taken+","+reserve()+")\n" ;
            }

            else if(isDigit()){     //判断是不是数字
                conCat();
                if(i+1 >= input.length) {
                    System.out.println("("+taken+","+digitCode+")");
                    put += "("+taken+","+digitCode+")\n" ;
                    return;
                }
                else
                    ch = input[++i] ;       //读取下个字符
                while (isDigit()){
                    conCat() ;
                    if(i+1 >= input.length) {
                        System.out.println("("+taken+","+digitCode+")");
                        put += "("+taken+","+digitCode+")\n" ;
                        return;
                    }
                    else
                        ch = input[++i] ;       //读取下个字符
                }
                ch = input[--i] ;         //回退一个字符
                System.out.println("("+taken+","+digitCode+")");
                put += "("+taken+","+digitCode+")\n" ;
            }
            else
                switch (ch){
                    case '>':
                        conCat();
                        if(i+1 >= input.length) {
                            System.out.println("("+taken+","+reserve()+")");
                            put += "("+taken+","+reserve()+")\n" ;
                            return;
                        }
                        else
                            ch = input[++i] ;       //读取下个字符

                        if(ch == '='){
                            conCat();
                            System.out.println("("+taken+","+reserve()+")");
                            put += "("+taken+","+reserve()+")\n" ;
                            break;
                        }
                        else {
                            ch = input[--i];
                            System.out.println("(" + taken + "," + reserve() + ")");
                            put += "("+taken+","+reserve()+")\n" ;
                            break;
                        }
                    case '<':
                        conCat();
                        if(i+1 >= input.length) {
                            System.out.println("("+taken+","+reserve()+")");
                            put += "("+taken+","+reserve()+")\n" ;
                            return;
                        }
                        else
                            ch = input[++i] ;       //读取下个字符

                        if(ch == '=' || ch== '>'){
                            conCat();
                            System.out.println("("+taken+","+reserve()+")");
                            put += "("+taken+","+reserve()+")\n" ;
                            break;
                        }
                        else {
                            ch = input[--i] ;
                            System.out.println("("+taken+","+reserve()+")");
                            put += "("+taken+","+reserve()+")\n" ;
                            break;
                        }
                    default:
                        conCat();
                        System.out.println("("+taken+","+reserve()+")");
                        put += "("+taken+","+reserve()+")\n" ;
                        break;
                }
        }
    }

    public static void main(String[] args) {
        launch(args);
    }
}

测试:

评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值