Package litil.parser

Source Code of litil.parser.TDTypeParser

package litil.parser;

import litil.ast.Type;
import litil.lexer.BaseLexer;
import litil.lexer.LookaheadLexer;
import litil.lexer.LookaheadLexerWrapper;
import litil.lexer.Token;

import java.io.InputStreamReader;
import java.io.Reader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class TDTypeParser extends BaseParser {
    public TDTypeParser(LookaheadLexer lexer) {
        super.lexer = lexer;
    }

    public static void main(String[] args) throws Exception {
        Reader reader = new InputStreamReader(LitilParser.class.getResourceAsStream("test.types"));
        TDTypeParser p = new TDTypeParser(new LookaheadLexerWrapper(new BaseLexer(reader)));
        p.debug = false;

        p.types();

    }

    private List<Type> types() {
        List<Type> res = new ArrayList<Type>();
        Type t = type();
        res.add(t);
        System.err.println(t);
        while (found(Token.Type.NEWLINE)) {
            t = type();
            res.add(t);
            System.err.println(t + "::" + t.getClass());
        }

        return res;
    }

    private Type type() {
        return funcType(new HashMap<String, Type.Variable>());
    }

    private Type type(Map<String, Type.Variable> mappings) {
        return funcType(mappings);
    }

    private Type funcType(Map<String, Type.Variable> mappings) {
        Type arg = prodType(mappings);
        if (found(Token.Type.SYM, "->")) {
            Type res = funcType(mappings);
            return Type.Function(arg, res);
        }
        return arg;
    }

    private Type prodType(Map<String, Type.Variable> mappings) {
        List<Type> args = new ArrayList<Type>();
        args.add(paramType(mappings));
        while (found(Token.Type.SYM, "*")) {
            args.add(paramType(mappings));

        }
        return args.size() == 1 ? args.get(0) : Type.Product(args);
    }

    private Type paramType(Map<String, Type.Variable> mappings) {
        if (found(Token.Type.NAME)) {
            String name = token.text;

            if (Character.isLowerCase(name.charAt(0))) {
                Type.Variable res;
                if (mappings.containsKey(name)) {
                    res = mappings.get(name);
                } else {
                    Type.Variable v = new Type.Variable();
                    mappings.put(name, v);
                    res = v;
                }
                if (lookahead(Token.Type.SYM, "(") || lookahead(Token.Type.SYM, "[") || lookahead(Token.Type.NAME)) {
                    throw error("Invalid type declaration: variables cannot be parameterized");
                } else {
                    return res;
                }
            } else {
                List<Type> args = new ArrayList<Type>();
                while (lookahead(Token.Type.SYM, "(") || lookahead(Token.Type.SYM, "[") || lookahead(Token.Type.NAME)) {
                    args.add(atomType(mappings));
                }
                if (args.isEmpty()) {
                    return typeFor(name);
                } else {
                    return new Type.Oper(name, args);
                }
            }
        } else {
            return atomType(mappings);
        }

    }

    private Type atomType(Map<String, Type.Variable> mappings) {
        if (found(Token.Type.SYM, "(")) {
            Type res = type(mappings);
            expect(Token.Type.SYM, ")");
            return res;
        } else if (found(Token.Type.SYM, "[")) {
            Type res = type(mappings);
            expect(Token.Type.SYM, "]");
            return Type.List(res);
        } else if (found(Token.Type.NAME)) {
            String name = token.text;
            if (Character.isLowerCase(name.charAt(0))) {
                if (mappings.containsKey(name)) {
                    return mappings.get(name);
                } else {
                    Type.Variable v = new Type.Variable();
                    mappings.put(name, v);
                    return v;
                }
            } else {
                return typeFor(token.text);
            }
        } else {
            throw error("Unexpected token");
        }
    }

    private Type typeFor(String name) {
        if("Number".equals(name)) {
            return Type.INT;
        } else if("String".equals(name)) {
            return Type.STR;
        } else if("Char".equals(name)) {
            return Type.CHAR;
        } else if("Bool".equals(name)) {
            return Type.BOOL;
        } else {
            return new Type.Oper("_"+name);
        }
    }


}
TOP

Related Classes of litil.parser.TDTypeParser

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.