自定义状态机解决分段代码块

通常包含一组状态、事件、状态之间的转换规则。状态机的目的是描述系统在不同状态下对事件的响应以及状态之间的切换过程

--greenplum分割do函数、存储过程
 private static String[] parseSQL(String sql) {
        List<String> sqlList = new ArrayList<>();
        // 先设置状态
        final int OUTSIDE_PROCEDURE = 0, IN_PROCEDURE = 1,
                IN_DO = 2, IN_STRING = 3,
                IN_LINE_COMMENT = 4, IN_MULTI_LINE_COMMENT = 5,
                IN_DO_LABEL = 6;

        int state = OUTSIDE_PROCEDURE;

        StringBuilder statementBuilder = new StringBuilder();
        StringBuilder labelBuilder = new StringBuilder(); // 用于记录label的内容
        StringBuilder label2 = new StringBuilder(); // 用于记录label的内容

        for (int i = 0; i < sql.length(); i++) {
            char c = sql.charAt(i);

            switch (state) {
                case OUTSIDE_PROCEDURE:
                    if (c == '-' && i + 1 < sql.length() && sql.charAt(i + 1) == '-') {
                        state = IN_LINE_COMMENT;
                        i++;
                    } else if (c == '/' && i + 1 < sql.length() && sql.charAt(i + 1) == '*') {
                        state = IN_MULTI_LINE_COMMENT;
                        statementBuilder.append(c);  // 追加注释开始符号到语句构建器
                    } else {
                        statementBuilder.append(c);
                        if (c == '$' && i + 1 < sql.length() && sql.charAt(i + 1) == '$') {
                            state = IN_PROCEDURE;
                            statementBuilder.append(sql.charAt(i + 1));
                            i++;
                        } else if (c == '$' && i + 1 < sql.length() && Character.isJavaIdentifierPart(sql.charAt(i + 1))) {
                            labelBuilder.setLength(0); // 清空labelBuilder
                            labelBuilder.append(c);
                            state = IN_DO;

                        } else if (c == '\'') {
                            state = IN_STRING;
                        } else if (c == ';') {
                            addSqlToList(statementBuilder.toString().trim(), sqlList);
                            statementBuilder.setLength(0);  // 清空语句缓存
                        }
                    }
                    break;
                case IN_PROCEDURE:
                    statementBuilder.append(c);
                    if (c == '$' && statementBuilder.toString().endsWith("$$")) {
                        state = OUTSIDE_PROCEDURE;
                    }
                    break;
                case IN_DO:
                    statementBuilder.append(c);
                    labelBuilder.append(c);
                    if (c == '$') {
                        state = IN_DO_LABEL;
                    }
                    break;
                case IN_DO_LABEL:

                    if (labelBuilder.toString().equals(label2.toString())) {
                        state = OUTSIDE_PROCEDURE;
                        label2.setLength(0);
                    } else if (c == '$') {
                        int endIdx = parseDollarQuotes(sql.toCharArray(), i);
                        if (endIdx != i) {
                            label2.append(sql, i, endIdx + 1);
                            statementBuilder.append(sql, i, endIdx + 1);
                            i = endIdx;
                        } else {
                            statementBuilder.append(c);
                        }

                    } else {
                        statementBuilder.append(c);
                    }
                    break;
                case IN_STRING:
                    statementBuilder.append(c);
                    if (c == '\'') {
                        state = OUTSIDE_PROCEDURE;
                    }
                    break;
                case IN_LINE_COMMENT:
                    if (c == '\n' || c == '\r') {
                        state = OUTSIDE_PROCEDURE;
                    }
                    break;
                case IN_MULTI_LINE_COMMENT:
                    statementBuilder.append(c);
                    if (c == '*' && i + 1 < sql.length() && sql.charAt(i + 1) == '/') {
                        state = OUTSIDE_PROCEDURE;
                        statementBuilder.append(sql.charAt(++i));  // 追加注释结束符号到语句构建器
                    } else if (c == '/' && i + 1 < sql.length() && sql.charAt(i + 1) == '*') {
                        // 处理 /* 嵌套 */ 的情况
                        state = IN_MULTI_LINE_COMMENT;
                        statementBuilder.append(c);
                        i++;
                    }
                    break;
                default:
                    // 处理其他状态(如果有的话)
            }
        }

        // 处理最后一条语句
        if (statementBuilder.length() > 0) {
            addSqlToList(statementBuilder.toString().trim(), sqlList);
        }
        return sqlList.toArray(new String[0]);
    }

    private static boolean ifBlockComment(String sql) {
        if (sql.trim().startsWith("/*") && sql.trim().endsWith("*/")) {
            // /* */作为注释不能作为单独一条sql执行,不能保留在末尾
            return true;
        }
        return false;
    }

    public static int parseDollarQuotes(char[] query, int offset) {
        int endIdx = -1;
        if (offset + 1 < query.length - 1 && (offset == 0 || !Character.isJavaIdentifierPart(query[offset - 1]))) {

            int d;
            if (query[offset + 1] == '$') {
                endIdx = offset + 1;
            } else if (isDollarQuoteStartChar(query[offset + 1])) {
                for (d = offset + 2; d < query.length - 1; ++d) {
                    if (query[d] == '$') {
                        endIdx = d;
                        break;
                    }

                    if (!isDollarQuoteContChar(query[d])) {
                        break;
                    }
                }
            }

        }
        if (endIdx > 0) {
            return endIdx;
        }
        return offset;
    }

    public static boolean isDollarQuoteStartChar(char c) {
        return c != '$' && Character.isJavaIdentifierStart(c);
    }

    public static boolean isDollarQuoteContChar(char c) {
        return c != '$' && Character.isJavaIdentifierPart(c);
    }


    /**
     * 将单句sql添加到list中
     *
     * @param sql     1、正常sql 2、可能包含分号,但是是一个错误sql("……;)
     * @param sqlList 用于存储拆分的sql
     */
    private static void addSqlToList(String sql, List<String> sqlList) {
        if (StringUtils.isEmpty(sql) || ifBlockComment(sql)) {
            return;
        }

        if (sql.charAt(sql.length() - 1) != ';') {
            sql += ";";
        }
        System.out.println("SQL输出:" + sql);
        sqlList.add(sql);
    }

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
VHDL状态机发光二极管代码主要是使用VHDL语言编写的,通过状态机实现发光二极管的控制。下面是一个简单的VHDL状态机发光二极管代码示例: ```vhdl library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity LED_Controller is port ( clk : in std_logic; -- 输入时钟信号 reset : in std_logic; -- 复位信号 LED : out std_logic_vector(3 downto 0) -- 输出LED信号 ); end entity; architecture Behavioral of LED_Controller is -- 枚举状态 type State is (S0, S1, S2, S3); -- 定义当前状态和下一个状态 signal current_state, next_state : State; begin -- 状态转移逻辑 process (clk, reset) begin if reset = '1' then -- 复位信号为高时,初始化为状态S0 current_state <= S0; elsif rising_edge(clk) then -- 上升沿触发状态转移 current_state <= next_state; end if; end process; -- 状态控制逻辑 process (current_state) begin case current_state is when S0 => -- 状态S0,LED1亮,其他灭 LED <= "1110"; next_state <= S1; when S1 => -- 状态S1,LED2亮,其他灭 LED <= "1101"; next_state <= S2; when S2 => -- 状态S2,LED3亮,其他灭 LED <= "1011"; next_state <= S3; when S3 => -- 状态S3,LED4亮,其他灭 LED <= "0111"; next_state <= S0; when others => null; end case; end process; end Behavioral; ``` 以上代码实现了一个简单的四个发光二极管的循环闪烁效果。在代码中定义了四个状态S0-S3,每个状态下控制不同的LED亮灭状态,并通过状态转移实现循环闪烁效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值