parser.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. package parser
  2. import (
  3. "fmt"
  4. "code.osinet.fr/fgm/waiig15/ast"
  5. "code.osinet.fr/fgm/waiig15/lexer"
  6. "code.osinet.fr/fgm/waiig15/token"
  7. )
  8. // Precedence constants.
  9. const (
  10. _ int = iota
  11. LOWEST
  12. EQUALS // ==
  13. LESSGREATER // > or <
  14. SUM // +
  15. PRODUCT // *
  16. PREFIX // -X or !X
  17. CALL // myFunction(X)
  18. )
  19. // Parser implements the parsing mechanism top-level layer.
  20. type Parser struct {
  21. errors []string
  22. l *lexer.Lexer
  23. curToken token.Token
  24. peekToken token.Token
  25. prefixParseFns map[token.TokenType]prefixParseFn
  26. infixParseFns map[token.TokenType]infixParseFn
  27. }
  28. type (
  29. prefixParseFn func() ast.Expression
  30. infixParseFn func(ast.Expression) ast.Expression
  31. )
  32. // New returns a new Parser instance with the first two parser tokens already
  33. // loaded.
  34. func New(l *lexer.Lexer) *Parser {
  35. p := &Parser{
  36. l: l,
  37. errors: []string{},
  38. }
  39. p.prefixParseFns = make(map[token.TokenType]prefixParseFn)
  40. p.registerPrefix(token.IDENT, p.parseIdentifier)
  41. p.registerPrefix(token.INT, p.parseIntegerLiteral)
  42. // Read two tokens, so curToken and peeToken are both set.
  43. p.nextToken()
  44. p.nextToken()
  45. return p
  46. }
  47. // Errors is a getter for Parser.errors.
  48. func (p *Parser) Errors() []string {
  49. return p.errors
  50. }
  51. // ParseProgram is the outermost parsing logic, accumulating statements in a
  52. // Program instance and returning that instance once parsing is done.
  53. func (p *Parser) ParseProgram() *ast.Program {
  54. program := &ast.Program{
  55. Statements: []ast.Statement{},
  56. }
  57. for !p.curTokenIs(token.EOF) {
  58. stmt := p.parseStatement()
  59. if stmt != nil {
  60. program.Statements = append(program.Statements, stmt)
  61. }
  62. p.nextToken()
  63. }
  64. return program
  65. }
  66. // Is the current token in the parser of the given type ?
  67. func (p *Parser) curTokenIs(t token.TokenType) bool {
  68. return p.curToken.Type == t
  69. }
  70. // Is the next token in the parser of the given type ? If it is, consume it,
  71. // else don't.
  72. func (p *Parser) expectPeek(t token.TokenType) bool {
  73. if p.peekTokenIs(t) {
  74. p.nextToken()
  75. return true
  76. }
  77. p.peekError(t)
  78. return false
  79. }
  80. func (p *Parser) nextToken() {
  81. p.curToken = p.peekToken
  82. p.peekToken = p.l.NextToken()
  83. }
  84. func (p *Parser) parseStatement() ast.Statement {
  85. switch p.curToken.Type {
  86. case token.LET:
  87. return p.parseLetStatement()
  88. case token.RETURN:
  89. return p.parseReturnStatement()
  90. default:
  91. return p.parseExpressionStatement()
  92. }
  93. }
  94. // Log a mismatch error on the peek token type in the parser instance.
  95. //
  96. // - t is the type of token that was expected
  97. func (p *Parser) peekError(t token.TokenType) {
  98. msg := fmt.Sprintf("expected next token to be %s, got %s instead",
  99. t, p.peekToken.Type)
  100. p.errors = append(p.errors, msg)
  101. }
  102. // Is the next token in the parser of the given type ? Don't consume it.
  103. func (p *Parser) peekTokenIs(t token.TokenType) bool {
  104. return p.peekToken.Type == t
  105. }