lexical.java

来自「一个用JAVA做的」· Java 代码 · 共 241 行

JAVA
241
字号
/* * To change this template, choose Tools | Templates * and open the template in the editor. */package srtpv02;import java.util.*;import java.io.*;import java.util.logging.Level;import java.util.logging.Logger;import java.util.regex.Matcher;import java.util.regex.Pattern;/** * * @author Administrator */public class Lexical {    public Lexical(String fileName) {        try {            Scanner sc = new Scanner(new File("symbols.ini"));            dutou = new Scanner(new File(fileName));            while (sc.hasNext()) {                keyWord.add(sc.next());            }        } catch (FileNotFoundException ex) {            Logger.getLogger(Lexical.class.getName()).log(Level.SEVERE, null, ex);            System.exit(1);        }    }    public void run() throws Exception {        int preLine = -1;        int currentLine = -1;        Node currentNode;        while (dutou.hasNext()) {            String currentToken = dutou.next();            currentNode = new Node();            currentNode.symbol = currentToken;            if (isKeyWord(currentToken)) {                currentNode.type = Type.KEYWORD;            } else if (isVariable(currentToken)) {                currentNode.type = Type.VARIABLE;            } else if (isNum(currentToken)) {                currentNode.type = Type.NUM;            } else if (isString(currentToken)) {                String temp = currentNode.symbol;                do {                    if (temp.charAt(temp.length() - 1) == '"') {                        break;                    }                    temp = dutou.next();                    currentNode.symbol = currentNode.symbol.concat(" " + temp);                }while(dutou.hasNext());                currentNode.type = Type.STRING;                currentNode.symbol = currentNode.symbol.substring(1, currentNode.symbol.length() - 1);            } else if (isOther(currentToken)) {                //暂时还不知道                continue;            } else if (isLineNum(currentToken)) {                currentLine = Integer.parseInt(currentToken.substring(0, currentToken.length() - 1));                if (currentLine > preLine) {                    preLine = currentLine;                    currentNode.type = Type.LINE;                    currentNode.symbol = currentToken.substring(0, currentToken.length() - 1);                } else {                    throw new Exception("The line num must increases progressively.See line "+ currentLine);                }            } else if (true) {                throw new Exception(currentNode.symbol + "in line " + currentLine + "unrecognized" );            }            tokens.add(currentNode);        }    }    public List<Node> getTokens() {        return tokens;    }    //是否是关键字    private boolean isKeyWord(String word) {        return keyWord.contains(word);    }    //是否是合法的变量名,即首字母为字母,后面为字母或数字    private boolean isVariable(String word) {        char currentChar = word.charAt(0);        if (isLetter(currentChar)) {            for (int i = 1; i < word.length(); ++i) {                currentChar = word.charAt(i);                if (isLetter(currentChar) || isDigit(currentChar)) {                    continue;                } else {                    return false;                }            }            return true;        } else {            return false;        }    }    //是否是合法的数字,暂时只支持整数    private boolean isNum(String word) {        char currentChar;        for (int i = 0; i < word.length(); ++i) {            currentChar = word.charAt(i);            if (!isDigit(currentChar)) {                return false;            }        }        return true;    }    //是否是行号,由一个整数加L表示,暂时必须使用行号,后续版本打算不要    private boolean isLineNum(String word) {        for (int i = 0; i < word.length() - 1; ++i)            if (!isDigit(word.charAt(i))) {                return false;            }        if (word.charAt(word.length() - 1) == 'L') {            return true;        } else {            return false;        }    }    //是否是字符串,首尾字母必须是"",//且串中不允许出现"    private boolean isString(String word) {        if (word.charAt(0) == '"') {            return true;        } else {            return false;        }    }    //是否是其他。。。。,其他什么东西?    private boolean isOther(String word) {        return false;    }    private boolean isLetter(char currentChar) {        return (currentChar >= 'a' && currentChar <= 'z') ||                (currentChar >= 'A' && currentChar <= 'Z');    }    private boolean isDigit(char letter) {        return (letter >= '0' && letter <= '9');    }    //private Pattern wordMatch = Pattern.compile("//w(//w | //d)");    // 词法分析时是否应该确定在内存中位置??暂时认为不需要    private Scanner dutou;    private Set<String> keyWord = new HashSet<String>();    //现在不确定符号表,行么。。。?    //private Set<Node> symbolTable = new HashSet<Node>();    private List<Node> tokens = new LinkedList<Node>();    public static void main(String[] args) {        Lexical myLex = new Lexical("test.sip");        try {            myLex.run();            for (Node node : myLex.getTokens()) {                System.out.println(node.symbol + "   " + node.type);            }        } catch (Exception ex) {            //System.out.println(ex.toString());            ex.printStackTrace();        }    }}enum Type {    LINE {        public String toString() {            return "line";        }    },    STRING {        @Override        public String toString() {            return "string";        }    }, NUM {        public String toString() {            return "num";        }    }, VARIABLE {        public String toString() {            return "variable";        }    }, KEYWORD {        @Override        public String toString() {            return "keyWord";        }    };  //行号,字符串,数字,变量    }//读头下当前单词的信息class Node {    @Override    public int hashCode() {        return type.hashCode();    }    @Override    public boolean equals(Object obj) {        if (obj == null) {            return false;        }        if (getClass() != obj.getClass()) {            return false;        }        final Node other = (Node) obj;        if ((this.symbol == null) ? (other.symbol != null) : !this.symbol.equals(other.symbol)) {            return false;        }        if (this.type != other.type) {            return false;        }        return true;    }    String symbol;    Type type;              //表示该符号的类型    int location;           //放在内存中的位置,若类型为行号,则此值表示为生成代码对应的行号    int where;              //当类型为变量时,若为数字,则为0,为字符串则为1,同上    //boolean isKeyWord = false;    }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?