Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
110 lines (90 sloc) 3.35 KB

2.6 节的练习

2.6.1

扩展 2.6.5 节中的词法分析器以消除注释。注释的定义如下:

  1. 以 // 开始的注释,包括从它开始到这一行结尾的呃所有字符
  2. 以 /* 开始的注释,包括从它到后面第一次出现的字符序列 */ 之间的所有字符

2.6.2

扩展 2.6.5 节中的词法分析器,使他能够识别关系运算符 <、 <=、 ==、 !=、 >=、 >

2.6.3

扩展 2.6.5 节中的词法分析器,使他能够识别浮点数,如 2.、3.14 和 .5 等等

解答

查看源码:

commit 8dd1a9a

可能会存在的问题:

  • 代码中没有游标,所以当最后一次获取的 peek 仅作为判断条件,而不是返回 token 的组成部分时,下一次 scan() 就会有问题
  • 当扫描到单个 '/',后面不跟 '/' 或 '*' 时抛异常,而需要根据语法判断这种情况下是不是把 '/' 作为一个新的 token 返回

代码片段(src/lexer/Lexer.java):

public Token scan() throws IOException, SyntaxException{
    for(;;peek = (char)stream.read()){
        if(peek == ' ' || peek == '\t'){
            continue;
        }else if(peek == '\n'){
            line = line + 1;
        }else{
            break;
        }
    }
    
    // handle comment
    if(peek == '/'){
        peek = (char) stream.read();
        if(peek == '/'){
            // single line comment
            for(;;peek = (char)stream.read()){
                if(peek == '\n'){
                    break;
                }
            }
        }else if(peek == '*'){
            // block comment
            char prevPeek = ' ';
            for(;;prevPeek = peek, peek = (char)stream.read()){
                if(prevPeek == '*' && peek == '/'){
                    break;
                }
            }
        }else{
            throw new SyntaxException();
        }
    }
    
    // handle relation sign
    if("<=!>".indexOf(peek) > -1){
        StringBuffer b = new StringBuffer();
        b.append(peek);
        peek = (char)stream.read();
        if(peek == '='){
            b.append(peek);
        }
        return new Rel(b.toString());
    }
    
    // handle number, no type sensitive
    if(Character.isDigit(peek) || peek == '.'){
        Boolean isDotExist = false;
        StringBuffer b = new StringBuffer();
        do{
            if(peek == '.'){
                isDotExist = true;
            }
            b.append(peek);
            peek = (char)stream.read();
        }while(isDotExist == true ? Character.isDigit(peek) : Character.isDigit(peek) || peek == '.');
        return new Num(new Float(b.toString()));
    }
    
    // handle word
    if(Character.isLetter(peek)){
        StringBuffer b = new StringBuffer();
        do{
            b.append(peek);
            peek = (char)stream.read();
        }while(Character.isLetterOrDigit(peek));
        String s = b.toString();
        Word w = words.get(s);
        if(w == null){
            w = new Word(Tag.ID, s);
            words.put(s, w);
        }
        return w;
    }
    
    Token t = new Token(peek);
    peek = ' ';
    return t;
}