LoginSignup
0
1

構文解析のやつ

Last updated at Posted at 2023-12-27

みなさまお久しぶりでございます。
アドオンシリーズは更新していません()
また機会があれば更新しようかと思います(投げやり)

とりあえず自分用メモ

Lexer.java
public class Lexer {
    private static final ArrayList<String> list = new ArrayList<>(); // 結果
    // 検知する文字とか
    private static final List<Character> brackets = Arrays.asList('(',')','{','}','[',']');
    private static final List<Character> operators = Arrays.asList('=','+','-','*','/');
    private static final List<Character> strings = Arrays.asList('\'','"');
    private static final List<Character> splits = Arrays.asList(',', ';');

    private static String s = "";
    private static boolean isString = false; // 文字列が始まったかどうか
    private static char startString = ' '; // 文字展開の最初に",'の二種類あるので"で始まったが'で終わらないようにするための対策

    private static Type getType(final Character c){ // タイプ判定。ここのクラスTypeは後述。
        if(Character.isLetter(c)) return Type.alphabet;
        else if(Character.isDigit(c)) return Type.digit;
        else if(Character.isWhitespace(c)) return Type.space;
        else if(operators.contains(c)) return Type.operator;
        else if(brackets.contains(c)) return Type.bracket;
        else if(strings.contains(c)) return Type.string;
        else if(splits.contains(c)) return Type.split;
        return Type.other;
    }

    public static void analyze(char c){
        Type type = getType(c);
        if(!isString){ // 文字列内ではない
            if(type.equals(Type.other)){
                System.out.println("その文字は使用不可能です: " + c);
                return;
            }
            if(type.equals(Type.alphabet)){
                s += c;
            } else if(type.equals(Type.digit)){
                s += c;
            }else if(type.equals(Type.space)){
                if(!s.equals("")) {
                    list.add(s);
                }
                s = "";
            }else if(type.equals(Type.operator)){
                if(!s.equals("")) {
                    list.add(s);
                }
                s = "";
                s += c;
                list.add(s);
                s = "";
            }else if(type.equals(Type.bracket)){
                if(!s.equals("")) {
                    list.add(s);
                }
                s = "";
                s += c;
                list.add(s);
                s = "";
            }else if(type.equals(Type.split)){
                if(!s.equals("")) {
                    list.add(s);
                }
                s = "";
                s += c;
                list.add(s);
                s = "";
            }else if(type.equals(Type.string)){
                if(!s.equals("")) {
                    list.add(s);
                }
                s = "";
                s += c;
                list.add(s);
                s = "";
                startString = c;
                isString = true;
            }
        }else{ // 文字列内の処理
            if(c == startString){ // 文字列の終端
                if(!s.equals("")) {
                    list.add(s);
                }
                s = "";
                s += c;
                list.add(s);
                s = "";
                startString = ' ';
                isString = false;
            }else{
                s += c; // 文字列内なら何も気にせず増やす
            }
        }
    }

    public static void endAnalyze(){ // 最後残ったやつを追加
        if(!s.equals("")) {
            list.add(s);
            s = "";
        }
    }
    
    public static void listRefresh(){ // 初期化
        list.clear(); // リスト削除
        s = ""; // ためておいた文字列消去
        isString = false; // 文字列の外判定にする
        startString = ' '; // 文字列の外判定なので初期化
    }

    public static ArrayList<String> getList(){ // リストがprivateなので
        return list;
    }
}

Type.javaも記述。
たった数行

Type.java
public enum Type {
    alphabet,
    digit,
    space,
    operator,
    bracket,
    other,
    string,
    split
}

ただのEnumですね。カンタン。

これは1文字ずつ解析するタイプなのでforで文字列ぶん回してください。

example.java
Lexer.listRefresh(); // 最初に初期化しておくと良き
String test = "解析する文字列";
for (char c : test.toCharArray()){
    Lexer.analyze(c);
}
Lexer.endAnalyze(); // 終了したので
System.out.println(Lexer.getList()); // 処理の結果を表示する。

ここを参考にして作りました。ありがとうございました。

まぁこんなもんですかね。近いうちアドオンシリーズは更新したいです。
またJavaの方も買ったのでまたmodシリーズとかやるかもしれません。

追記(まだ増えるかも)
気づいたらまじ1年経ってる...
更新頻度がやばい

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1