- 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:
Tijani Lawal 2022-05-26 19:23:01 +00:00
parent 4a3edec5e6
commit 145d61ba57
2 changed files with 39 additions and 10 deletions

View File

@ -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
}
}

View File

@ -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()
}