|
|
@@ -27,6 +27,18 @@ const (
|
|
|
CALL // myFunction(X)
|
|
|
)
|
|
|
|
|
|
+// 指派 token 类型的优先级
|
|
|
+var precedences = map[token.TypeToken]int{
|
|
|
+ token.EQ: EQUALS,
|
|
|
+ token.NOT_EQ: EQUALS,
|
|
|
+ token.GT: LESSGREATER,
|
|
|
+ token.LT: LESSGREATER,
|
|
|
+ token.PLUS: SUM,
|
|
|
+ token.MINUS: SUM,
|
|
|
+ token.ASTERISK: PRODUCT,
|
|
|
+ token.SLASH: PRODUCT,
|
|
|
+}
|
|
|
+
|
|
|
type (
|
|
|
prefixParseFn func() ast.Expression
|
|
|
infixParseFn func(expression ast.Expression) ast.Expression
|
|
|
@@ -55,6 +67,16 @@ func New(l *lexer.Lexer) *Parser {
|
|
|
p.registerPrefix(token.BANG, p.parsePrefixExpression)
|
|
|
p.registerPrefix(token.MINUS, p.parsePrefixExpression)
|
|
|
|
|
|
+ p.infixParseFns = make(map[token.TypeToken]infixParseFn)
|
|
|
+ p.registerInfix(token.PLUS, p.parseInfixExpression)
|
|
|
+ p.registerInfix(token.MINUS, p.parseInfixExpression)
|
|
|
+ p.registerInfix(token.ASTERISK, p.parseInfixExpression)
|
|
|
+ p.registerInfix(token.SLASH, p.parseInfixExpression)
|
|
|
+ p.registerInfix(token.EQ, p.parseInfixExpression)
|
|
|
+ p.registerInfix(token.NOT_EQ, p.parseInfixExpression)
|
|
|
+ p.registerInfix(token.GT, p.parseInfixExpression)
|
|
|
+ p.registerInfix(token.LT, p.parseInfixExpression)
|
|
|
+
|
|
|
// Read two tokens, so curToken and peekToken are both set
|
|
|
p.nextToken()
|
|
|
p.nextToken()
|
|
|
@@ -78,6 +100,19 @@ func (p *Parser) parseIntegerLiteral() ast.Expression {
|
|
|
|
|
|
return lit
|
|
|
}
|
|
|
+func (p *Parser) parseInfixExpression(left ast.Expression) ast.Expression {
|
|
|
+ exp := &ast.InfixExpression{
|
|
|
+ Token: p.curToken,
|
|
|
+ Left: left,
|
|
|
+ Operator: p.curToken.Literal,
|
|
|
+ }
|
|
|
+
|
|
|
+ precedence := p.curPrecedence()
|
|
|
+ p.nextToken()
|
|
|
+ exp.Right = p.parseExpression(precedence)
|
|
|
+
|
|
|
+ return exp
|
|
|
+}
|
|
|
func (p *Parser) parsePrefixExpression() ast.Expression {
|
|
|
exp := &ast.PrefixExpression{
|
|
|
Token: p.curToken,
|
|
|
@@ -190,9 +225,18 @@ func (p *Parser) parseExpression(precedence int) ast.Expression {
|
|
|
p.noPrefixParseFnError(p.curToken.Type)
|
|
|
return nil
|
|
|
}
|
|
|
-
|
|
|
leftExp := prefix()
|
|
|
|
|
|
+ for !p.peekTokenIs(token.SEMICOLON) && precedence < p.peekPrecedence() {
|
|
|
+ infix := p.infixParseFns[p.peekToken.Type]
|
|
|
+ if infix == nil {
|
|
|
+ return leftExp
|
|
|
+ }
|
|
|
+ p.nextToken()
|
|
|
+
|
|
|
+ leftExp = infix(leftExp)
|
|
|
+ }
|
|
|
+
|
|
|
return leftExp
|
|
|
}
|
|
|
|
|
|
@@ -226,3 +270,15 @@ func (p *Parser) noPrefixParseFnError(t token.TypeToken) {
|
|
|
msg := fmt.Sprintf("no prefix parse function for %s found", t)
|
|
|
p.errors = append(p.errors, msg)
|
|
|
}
|
|
|
+func (p *Parser) peekPrecedence() int {
|
|
|
+ if p, ok := precedences[p.peekToken.Type]; ok {
|
|
|
+ return p
|
|
|
+ }
|
|
|
+ return LOWEST
|
|
|
+}
|
|
|
+func (p *Parser) curPrecedence() int {
|
|
|
+ if p, ok := precedences[p.curToken.Type]; ok {
|
|
|
+ return p
|
|
|
+ }
|
|
|
+ return LOWEST
|
|
|
+}
|