#前置き
バージョン | 環境 |
---|---|
jdk-10 | IntelliJ IDEA |
たぶん上の環境で動きます。 |
前の記事:[EAMを実装しよう]
(https://qiita.com/mirror11akii/items/c72c2d2a108a9b75fccb)
EAMの結果帰ってくるchar[]を字句解析するLexerを作ります。
昨日はかなりコードに欠陥があったのでかなり実力不足を感じ反省しました。迷惑かけた皆様申し訳ございませんでした。問題があったら遠慮なくいってください。
##Lexerとは
Lexerとは、字句解析器(Lexical Analyzer)のことです。Parserとも呼ばれることがあるようですが、ParserをParser Combinatorと言ったりややこしくなるので、こちらを用います。さっそく実装を見てみましょう。
##実装
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;
}
}
public enum Type{
alphabet,
digit,
space,
operator,
//bracket,
other
}
##実装の説明
いや、自分でも汚いコードだと思います。これから修正していくつもりです。いい案がある人はぜひ教えてください。
bracketという文字がコメントでちらほら見えますが「かっこ」のことです。めんどくさいのでとりあえず後回しにしました。
public static Type getType(final Character c)
この部分で読んだ文字が何なのか調べます。
public static void addString()
ここでは、最後のトークンをリストに追加しています
##実行
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);
}
}
@FunctionalInterface
public interface Use<T,R,X extends Throwable>{
R apply(T t) throws X;
}
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]
こんな感じになれば成功です。分からないことがあれば質問してください。