Lexerを実装しよう(1)

#前置き
|バージョン|環境         |
|:-------:|:-----------:|
|jdk-10   |IntelliJ IDEA|
たぶん上の環境で動きます。

前の記事：[EAMを実装しよう]
(https://qiita.com/mirror11akii/items/c72c2d2a108a9b75fccb)
　EAMの結果帰ってくるchar[]を字句解析するLexerを作ります。
　昨日はかなりコードに欠陥があったのでかなり実力不足を感じ反省しました。迷惑かけた皆様申し訳ございませんでした。問題があったら遠慮なくいってください。
##Lexerとは
　Lexerとは、字句解析器(Lexical Analyzer)のことです。Parserとも呼ばれることがあるようですが、ParserをParser Combinatorと言ったりややこしくなるので、こちらを用います。さっそく実装を見てみましょう。
##実装
```java:Lexer.java
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Lexer {
    static String s = "";
    static List<String> l= new ArrayList<>();

    //private static List<Character> brackets = Arrays.asList('(',')','{','}','[',']');
    private static List<Character> operators = Arrays.asList('=','+','-','*','/');

    public static Type getType(final Character c){
        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.brackets;
        return Type.other;
    }
    public static void analyze(char c){
        switch (getType(c)) {
            case other:
                System.out.println("This character cannot be accepted");
                break;
            case space:
                if(s != ""){
                    l.add(s);
                    s = "";
                }
                break;
            //case bracket:
            case operator:
                if(s != ""){
                    l.add(s);
                    l.add(""+c);
                    s = "";
                    break;
                }
            case alphabet:
            case digit:
                s += c;
            default: break;
        }
    }
    public static void addString(){
        l.add(s);
    }
    public static List<String> getList(){
        return l;
    }
}
```
```java:Type.java
public enum Type{
    alphabet,
    digit,
    space,
    operator,
    //bracket,
    other
}
```
##実装の説明
　いや、自分でも汚いコードだと思います。これから修正していくつもりです。いい案がある人はぜひ教えてください。
　bracketという文字がコメントでちらほら見えますが「かっこ」のことです。めんどくさいのでとりあえず後回しにしました。

`public static Type getType(final Character c)`
この部分で読んだ文字が何なのか調べます。
`public static void addString()`
ここでは、最後のトークンをリストに追加しています
##実行
```java:EAM.java
import java.util.*;
import java.io.*;

public class EAM{
    private final FileReader fr;

    private EAM(final String s) throws IOException{
        fr = new FileReader(s);
    }
    public static char[] use(final String s,final Use<EAM,char[],IOException> u) throws IOException{
        final EAM eam = new EAM(s);
        char[] c;
        try{
            c = u.apply(eam);
        }finally{
            eam.close();
        }
        return c;
    }
    private void close() throws IOException{
        System.out.println("close()");
        fr.close();
    }
    public char[] read() throws IOException {
        char[] c = new char[100];
        int length = fr.read(c);
        return Arrays.copyOfRange(c, 0, length);
    }
}
```
```java:Use.java
@FunctionalInterface
public interface Use<T,R,X extends Throwable>{
	R apply(T t) throws X;
}
```
```java:Main.java
import java.io.IOException;

public class Main{
    public static void main(String[] args) throws IOException{
        char[] array = EAM.use("lib\\test.txt", eam -> eam.read());
        System.out.println("\n--EAM");
        for(char c : array){
            System.out.print(c);
            Lexer.analyze(c);
        }
        FLexer.addString();
        System.out.println( "\n--Lexer\n" + Lexer.getList());
    }
}
```
前回のEAMを使って読んでいます。メソッドの内容がところどころ違います。char[]を返せるようにしようと思ってこうしました。
####結果
```
close()

--EAM
a = 2 + 7 * 3
log a
--Lexer
[a, =, 2, +, 7, *, 3, log, a]
```
こんな感じになれば成功です。分からないことがあれば質問してください。