编译原理(紫龙书)中文第2版习题答案

 主页   资讯   文章   代码   电子书 

Exercises for Section 2.6

2.6.1

Extend the lexical analyzer in Section 2.6.5 to remove comments, defined as follows:

  1. A comment begins with // and includes all characters until the end of that line.
  2. A comment begins with / and includes all characters through the next occurrence of the character sequence /.

2.6.2

Extend the lexical analyzer in Section 2.6.5 to recognize the relational operators <, <=, ==, ! =, >=, >.

2.6.3

Extend the lexical analyzer in Section 2.6.5 to recognize floating point numbers such as 2., 3.14, and . 5.

Answer

Source code: commit 8dd1a9a

Code snippet(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;
}