parser.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. package parser
  2. import (
  3. "fmt"
  4. "github/runnignwater/monkey/ast"
  5. "github/runnignwater/monkey/lexer"
  6. "github/runnignwater/monkey/token"
  7. )
  8. /**
  9. * @Author: simon
  10. * @Author: ynwdlxm@163.com
  11. * @Date: 2022/10/2 下午9:55
  12. * @Desc:
  13. */
  14. type Parser struct {
  15. l *lexer.Lexer // point to the instance of the lexer
  16. curToken token.Token // point to the current token
  17. peekToken token.Token // point to the next token
  18. errors []string
  19. }
  20. func New(l *lexer.Lexer) *Parser {
  21. p := &Parser{
  22. l: l,
  23. errors: []string{},
  24. }
  25. // Read two tokens, so curToken and peekToken are both set
  26. p.nextToken()
  27. p.nextToken()
  28. return p
  29. }
  30. func (p *Parser) Errors() []string {
  31. return p.errors
  32. }
  33. func (p *Parser) peekError(t token.TypeToken) {
  34. msg := fmt.Sprintf("exepected next token to be %s, got %s instead.", t, p.peekToken.Type)
  35. p.errors = append(p.errors, msg)
  36. }
  37. func (p *Parser) nextToken() {
  38. p.curToken = p.peekToken
  39. p.peekToken = p.l.NextToken()
  40. }
  41. func (p *Parser) ParseProgram() *ast.Program {
  42. program := &ast.Program{}
  43. program.Statements = []ast.Statement{}
  44. for !p.curTokenIs(token.EOF) {
  45. stmt := p.parseStatement()
  46. if stmt != nil {
  47. program.Statements = append(program.Statements, stmt)
  48. }
  49. p.nextToken()
  50. }
  51. return program
  52. }
  53. func (p *Parser) parseStatement() ast.Statement {
  54. switch p.curToken.Type {
  55. case token.LET:
  56. return p.parseLetStatement()
  57. default:
  58. return nil
  59. }
  60. }
  61. // let <identifier> = <expression>;
  62. func (p *Parser) parseLetStatement() *ast.LetStatement {
  63. stmt := &ast.LetStatement{Token: p.curToken}
  64. if !p.expectPeek(token.IDENT) {
  65. return nil
  66. }
  67. stmt.Name = &ast.Identifier{Token: p.curToken, Value: p.curToken.Literal}
  68. if !p.expectPeek(token.ASSIGN) {
  69. return nil
  70. }
  71. // TODO: we're skipping the expression until we
  72. // we encounter a semicolon
  73. for !p.curTokenIs(token.SEMICOLON) {
  74. p.nextToken()
  75. }
  76. return stmt
  77. }
  78. func (p *Parser) curTokenIs(t token.TypeToken) bool {
  79. return p.curToken.Type == t
  80. }
  81. func (p *Parser) peekTokenIs(t token.TypeToken) bool {
  82. return p.peekToken.Type == t
  83. }
  84. func (p *Parser) expectPeek(t token.TypeToken) bool {
  85. if p.peekTokenIs(t) {
  86. p.nextToken()
  87. return true
  88. } else {
  89. p.peekError(t)
  90. return false
  91. }
  92. }