Skip to content
  • REPL

    • read-evaluate-print-loop
  • RPPL

    • read-parse-print-loop
  • for now

    • currently
  • in place

    • 到位,准备就绪
  • treated

    • 处理过
  • unintended

    • 非预期,无意的
  • As I said, this is where we decide how the language works.

  • seem like

  • make sense

    • 有意义,有道理
  • truthy

    • 诚实
  • of course

  • instead of ... or ...

    • 而不是
  • solely

    • 仅仅、唯独、完全
  • knock yourself out

  • strictly speaking

  • we added two new and concise functions

    • 简约、要言不烦、精炼
  • Supporting strings in our lexer

    • The first thing we have to do is add support for string literals to our lexer
    • That's not too hard, right?
    • It's time to teach the parser how to do the same.
    • Of course, string literals are exprestions and not statements.
    • With the definition we can write a small test case that make sure the parse knows how to handle token.STRING tokens and outputs *ast.StringLiterals
    • So now len is found when looking up the len identifier, calling it doesn't work ye.
    • That means that calling len works though
    • As we saw before.
    • Just to make sure that the parsing of expressions really works the test input contains two different infix operator expressions, even though integer or boolean literals would be enough.
    • off-by-one 逐一
    • one by one 逐个
    • Some languages produce an error in such a case and some return a null value.
    • I choose to return NULL.
    • As expected the tests are failing. And not noly that, they're blowing up.
    • So how do we fix this and evaluate index expressions?
    • As we've seen, the left operand of the index operator can be any expression and the index itself can be any expression.
    • Otherwise
    • Okay, now take a deep breath, relax and take a loot at this:
  • flesh out, flesh means body, 充实,开掘

  • represent - 重现?代表

    • present - 目前,现在
  • Personally, I think that parsing expressions is the most interseting part of writing a parser.

  • As we just saw, parsing statements is relatively straightforward.

  • What we want here is an AST that represents the expression like this:

    • What we want here
      • is an AST
        • that represents the expression like this?
          • that is an AST
  • In order to produce an AST that looks like this, the parser has to know about operator precedences where the precedence of * is higher than +.

  • That's the most common example for operator precedence, but there are a lot more cases where it's important.

  • Consider this expression.

    • parenthesis ()
    • parentheses ()
  • In contrast to this, the let token can only appear once at the beginning of a let statement, which makes it easy to determine what the rest of the statement is supposed to be.

    • determine -> make sure
    • supposed
      • be supposed to
        • to have to; to have a duty or a responsibility to
        • the children are supposed to be at school by 8.45 a.m
        • What are you doing out of bed - you're supposed to be asleep
        • You're not supposed(= allowed) to park here.
      • used to show that you do not believe that something or someone really is waht many other people consider them boe be
        • a supposed genuis
        • The costs of the programme outweight its supposed benefits.
  • the rest of

    • other
    • left
  • In the monkey programming language everything besides let and return statments is an expression. These expressions come in different varieties.

    • varieties -> kind of?
    • beside
      • Those books seem very dull beside this one.
        • dull - boring
  • infix operators -> binary operators

  • And of course, as we previously saw, we can use parentheses to group expressions and influence the order of evaluation.

    • influence - 影响
    • enfluence
  • first-class citizens

  • approach

  • Top Down Operator Precedence

    • ... is very simple to understand, trivial to implement, easy to use, extremely efficent in practice if not in theory, yet flexible enought to meet most reasonable syntacitc needs of users ...
  • I guess that doesn't make a lot of sense yet. We never saw how to associate parsing functions with grammaer rules, so the idea of using token types instead of these rules doesn't register as anything realy novel or revelatory. To be completely honest: I was facing a chicken and egg problem when writing this section.

  • Is it better to explain this algorithm in abstract terms and then show the implemetation, possibly causing you to jump back and forth between pages, or to show the implementation with the explanation following, causing your to probably skip over the implementation and not getting a lot out of the explanation?

  • The answer, I decided, is neither of these to options. What we're going to do instread is strat implementing the expression parsing part of our parser.

  • And before we start writing any code, let's just be clear on the terminology

    • terminology - 术语
  • A prefix operator is an operator "in front of" its operand.

  • This is going to be really handy in tests.

  • It's important to not that left is our already parsed *ast.IntegerLiteral that represents the 1.

https://dictionary.cambridge.org/zhs/%E8%AF%8D%E5%85%B8/%E8%8B%B1%E8%AF%AD-%E6%B1%89%E8%AF%AD-%E7%B9%81%E4%BD%93/supposed