Let's implement Lexer (2)

Preface

version environment
jdk-10 IntelliJ IDEA

Maybe it works in the above environment.

Previous article [Let's implement Lexer (1)] (https://qiita.com/mirror11akii/items/7fe6fd3143b9a1eb9683)

Supplement

This series is ** written with the desire to connect with people who sympathize with me, people who are interested in new languages, and java programmers who want to develop teams **. Of course, it is OK to use and browse for other purposes. However, I would be very happy if you would be interested in it, and it would be very helpful if you could tell me something in the comments.


I intend to make Lexer a little functional. Like Lexer, I felt that it was difficult to handle if the number of inputs and outputs was different and the number of outputs was not known.

Implementation

FLexer.java


import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Stack;

public class FLexer {

    static Stack<String> stack = new Stack();

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

    public static FType getType(final Character c){
        if(Character.isLetter(c)) return FType.alphabet;
        else if(Character.isDigit(c)) return FType.digit;
        else if(Character.isWhitespace(c)) return FType.space;
        else if(operators.contains(c)) return FType.operator;
        //else if(brackets.contains(c)) return FType.brackets;
        return FType.other;
    }
    public static List<Character> toList(final char[] chars){
        List<Character> list = new ArrayList<>();
        for(Character aChar : chars){
            list.add(aChar);
        }
        return list;
    }
    public static void analyze(final Character aChar){
        if(stack.empty()){
            stack.push(Character.toString(aChar));
        }else{
            final String previous = stack.pop();
            if(getType(aChar) == getType(previous.charAt(0))){
                stack.push(previous + aChar);
            }else{
                stack.push(previous);
                stack.push(Character.toString(aChar));
            }
        }
    }
    public static void disp(){
        System.out.println(stack);
    }
}

FType.java


public enum FType{
    alphabet,
    digit,
    space,
    operator,
    //bracket,
    other
}

Implementation description

I haven't implemented "parentheses" because it's troublesome, but I think it can be handled by increasing the if branch of analyze ().

public static List<Character> toList(...) I wanted to use a lambda expression, so I prepared a function to convert it to a list. public static void analyze(...) I thought that if I read the previous element, I could use a stack, so I made it a stack.

Run

Main.java


import java.io.IOException;

public class Main{
    public static void main(String[] args) throws IOException{
        System.out.println("\n--EAM");
        char[] chars = EAM.use("lib\\test.txt", eam -> eam.read());
        for (char aChar : chars) {
            System.out.print(aChar);
        }
        System.out.println( "\n--FLexer");
        FLexer.toList(chars).stream()
                            .forEach(FLexer::analyze);
        FLexer.disp();
    }
}
--EAM
close()
a = 2 + 7 * 3
log a
--FLexer
[a,  , =,  , 2,  , +,  , 7,  , *,  , 3, 
, log,  , a]

If it looks like this, it's a success. If you have any questions, please ask.

Recommended Posts

Let's implement Lexer (1)
Let's implement Lexer (2)
Let's implement EAM
Implement tail