- The parser can now check for errors.
- The test now handles checking for errors. git-svn-id: https://svn.tlawal.org/svn/monkey@19 f6afcba9-9ef1-4bdd-9b72-7484f5705bac
This commit is contained in:
parent
4a3edec5e6
commit
145d61ba57
@ -1,6 +1,7 @@
|
||||
package parser
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"monkey/ast"
|
||||
"monkey/lexer"
|
||||
"monkey/token"
|
||||
@ -10,10 +11,12 @@ type Parser struct {
|
||||
lexer *lexer.Lexer
|
||||
current_token token.Token
|
||||
peek_token token.Token
|
||||
|
||||
errors []string
|
||||
}
|
||||
|
||||
func New(l_lexer *lexer.Lexer) *Parser {
|
||||
l_parser := &Parser{lexer: l_lexer}
|
||||
l_parser := &Parser{lexer: l_lexer, errors: []string{}}
|
||||
|
||||
// Read two tokens so current_token and peek_token are both set
|
||||
l_parser.next_token()
|
||||
@ -22,6 +25,10 @@ func New(l_lexer *lexer.Lexer) *Parser {
|
||||
return l_parser
|
||||
}
|
||||
|
||||
func (l_parser *Parser) Errors() []string {
|
||||
return l_parser.errors
|
||||
}
|
||||
|
||||
func (l_parser *Parser) ParseProgram() *ast.Program {
|
||||
program := &ast.Program{}
|
||||
program.Statements = []ast.Statement{}
|
||||
@ -68,6 +75,21 @@ func (l_parser *Parser) parse_let_statement() *ast.LetStatement {
|
||||
return statement
|
||||
}
|
||||
|
||||
func (l_parser *Parser) expect_peek(l_token token.TokenType) bool {
|
||||
if l_parser.peek_token_is(l_token) {
|
||||
l_parser.next_token()
|
||||
return true
|
||||
} else {
|
||||
l_parser.peek_error(l_token)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (l_parser *Parser) peek_error(l_token token.TokenType) {
|
||||
message := fmt.Sprintf("expected next token to be %s, got %s", l_token, l_parser.peek_token.Type)
|
||||
l_parser.errors = append(l_parser.errors, message)
|
||||
}
|
||||
|
||||
func (l_parser *Parser) current_token_is(l_token token.TokenType) bool {
|
||||
return l_parser.current_token.Type == l_token
|
||||
}
|
||||
@ -75,12 +97,3 @@ func (l_parser *Parser) current_token_is(l_token token.TokenType) bool {
|
||||
func (l_parser *Parser) peek_token_is(l_token token.TokenType) bool {
|
||||
return l_parser.peek_token.Type == l_token
|
||||
}
|
||||
|
||||
func (l_parser *Parser) expect_peek(l_token token.TokenType) bool {
|
||||
if l_parser.peek_token_is(l_token) {
|
||||
l_parser.next_token()
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,8 @@ func TestLetStatement(l_test *testing.T) {
|
||||
l_parser := New(l_lexer)
|
||||
|
||||
program := l_parser.ParseProgram()
|
||||
check_parser_errors(l_test, l_parser)
|
||||
|
||||
if program == nil {
|
||||
l_test.Fatalf("ParseProgram() returned nil")
|
||||
}
|
||||
@ -65,3 +67,17 @@ func testLetStatement(l_test *testing.T, statement ast.Statement, name string) b
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func check_parser_errors(l_test *testing.T, l_parser *Parser) {
|
||||
errors := l_parser.Errors()
|
||||
if len(errors) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
l_test.Errorf("parser has %d errors", len(errors))
|
||||
|
||||
for _, message := range errors {
|
||||
l_test.Errorf("parser error: %q", message)
|
||||
}
|
||||
l_test.FailNow()
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user