munificent / craftinginterpreters

Repository for the book "Crafting Interpreters"
http://www.craftinginterpreters.com/
Other
8.75k stars 1.03k forks source link

A question on string() in Scanning/String literals (4.6.1) #972

Closed Origami404 closed 3 years ago

Origami404 commented 3 years ago

Hello, you book is amazing and I enjoy it very much. But the function string() in Scanning/String literals makes me a little confused.

private void string() {
    while (peek() != '"' && !isAtEnd()) {
      if (peek() == '\n') line++;
      advance();
    }

    if (isAtEnd()) {
      Lox.error(line, "Unterminated string.");
      return;
    }

    // ** Point A **

    // The closing ".
    advance();

    // Trim the surrounding quotes.
    String value = source.substring(start + 1, current - 1);
    addToken(STRING, value);
}

If the code run to Point A, that means peek() == '"' is statisfied, the current will reference to the character '"' like that:

start
|
"ABCD";
     |
     current

And then there is a advance(), which will change the current to the next character after '"':

start
|
"ABCD";
      |
      current

Now if I use source.substring(start + 1, current - 1) to get the literal, I will get "ABCD"; as lexeme and ABCD" as literal, which to my understanding is NOT what the code is designed to do.

I suggest to change the substring(start + 1, current - 1) to substring(start + 1, current - 2), so that I could get "ABCD" as lexeme and ABCD as literal. If I just move advance() to the end of the function I will get "ABCD as lexeme.

Sorry for any mistakes. English is not my native language.

Origami404 commented 3 years ago

Oh how stupid I am. The substr method in Java uses left-closed and right-opened interval. I am trying to implement the lox interpreter following the book by C++ and have ignored the difference between each languages' APIs.