Skip to content

Commit

Permalink
feat: add error support for parser v0
Browse files Browse the repository at this point in the history
  • Loading branch information
Houcine EL ADDALI committed Dec 9, 2023
1 parent eb62daa commit 62a1749
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 19 deletions.
44 changes: 37 additions & 7 deletions parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,14 @@ type Parser struct {
lexer *lexer.Lexer // points to the lexer
currToken token.Token // the current token in examination
peekedToken token.Token // the next token after the current one
errors []string
}

func InitParser(l *lexer.Lexer) *Parser{
p := &Parser{lexer: l}
p := &Parser{
lexer: l,
errors: []string{},
}

p.NextToken() // to peek the first token
p.NextToken() // first token in the currentToken
Expand All @@ -37,14 +41,24 @@ func (p *Parser) NextToken(){
p.currToken = p.peekedToken
p.peekedToken = p.lexer.NextToken()
}

/*
* function to return the encountered errors
* while parsing
*/

func (p *Parser) Errors() []string{
return p.errors
}

/*
This function is to parse a given program
*/
func (p *Parser) Parse() *ast.Program{
program := &ast.Program{}
program.Statements = []ast.Statement{};

for p.currToken.Type != token.FILE_ENDED {
for !p.currentTokenEquals(token.FILE_ENDED) {
stm := p.parseStmt()
//fmt.Println(stm.TokenLiteral())

Expand Down Expand Up @@ -80,15 +94,14 @@ func (p *Parser) parseDefStmt() *ast.DefStatement {
stm := &ast.DefStatement{Token: p.currToken}

// syntax error's
if !p.expectedNextToken(token.IDENTIFIER){
if !p.expectedNextToken(token.NewToken(token.IDENTIFIER,"IDENT")){
return nil
}
fmt.Println("------HERE-----------")
stm.Name = &ast.Identifier{
Token: p.currToken,
Value: p.currToken.Value,
}
if !p.expectedNextToken(token.ASSIGN){
if !p.expectedNextToken(token.NewToken(token.ASSIGN,"=")){
return nil
}

Expand All @@ -113,10 +126,27 @@ func (p *Parser) peekTokenEquals(t token.TokenType) bool {
* if it is returns true and advances the token
* if not returns false
*/
func (p *Parser) expectedNextToken(t token.TokenType) bool{
if p.peekTokenEquals(t){
func (p *Parser) expectedNextToken(t token.Token) bool{
if p.peekTokenEquals(t.Type){
p.NextToken()
return true
}
// peek errors
p.peekedError(t)
return false
}

/*
* function to peek Errors in next token
* takes the peeked wrong token and adds error
* message to the errors array of the parser
*/
func (p *Parser) peekedError(encounteredToken token.Token) {

errorMessage := fmt.Sprintf("wrong next token type expected token is %s instead got %s",
encounteredToken.Value, p.peekedToken.Value)

// append message to the errors array
p.errors =append(p.errors, errorMessage)

}
43 changes: 33 additions & 10 deletions parser/parser_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package parser

import (
"fmt"
"testing"

ast "github.com/houcine7/JIPL/AST"
Expand All @@ -11,20 +10,22 @@ import (
func TestDefStatement(t *testing.T) {

input := `
def num1 = 5;
def num2 = 10;
def foobar = 838383;
def num1 = 13;
def num2 = 0;
def foobar = 5321;
`
l := lexer.InitLexer(input)
fmt.Println("-----------------------")
fmt.Println("lexer", l)

t.Log("-----------------------")
t.Log("lexer", l)
parser := InitParser(l)
fmt.Println("-----------------------")
fmt.Println("parser",parser)
t.Log("-----------------------")
t.Log("parser",parser)

program := parser.Parse()

fmt.Println(program)
// check parser errors
checkParserErrors(parser,t)

if program==nil{
t.Fatalf("parse returned a nil value")
Expand All @@ -51,9 +52,30 @@ def foobar = 838383;
return
}
}

}



func checkParserErrors(p *Parser,t *testing.T){
errors := p.Errors()

if len(errors) ==0 {
t.Log("INFO: no ERRORS OCCURRED")
return
}

//
t.Log("-------PARSING ERRORS: --------")
t.Errorf("%d error found on the parser",len(errors))

for i,msg := range errors {
t.Errorf("Parser index:%d has message %s",i,msg)
}

t.FailNow() // mark tests as failed and stop execution
}


func testDefStatement(t *testing.T, stm ast.Statement, name string) bool {
if stm.TokenLiteral() !="def" {
t.Errorf("s.tokenLiteral is not 'def'. got instead:%q",stm.TokenLiteral())
Expand All @@ -80,3 +102,4 @@ func testDefStatement(t *testing.T, stm ast.Statement, name string) bool {
return true;
}


4 changes: 2 additions & 2 deletions token/token.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ type Token struct {
* Create a new token helper function
*/

func NewToken (tType TokenType, value string) Token{
func NewToken(tType TokenType, value string) Token{
return Token{Type: tType , Value: value};
}

Expand All @@ -42,4 +42,4 @@ func GetIdentifierTokenType(identifier string) TokenType{
return tokenType
}
return IDENTIFIER
}
}

0 comments on commit 62a1749

Please sign in to comment.