Chervil is a toy Lisp interpreter written in Ruby
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

parser.rb 1.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. module Chervil
  2. class Parser def initialize(lexer)
  3. @lexer = lexer
  4. @tree = Array.new
  5. @current_token = @lexer.get_next_token
  6. end
  7. def parse
  8. until @current_token.type == :eof
  9. @tree << expr
  10. end
  11. @tree
  12. end
  13. def expr
  14. if [:string, :number].include?(@current_token.type)
  15. constant
  16. elsif @current_token.type == :identifier
  17. identifier
  18. elsif @current_token.type == :lparen
  19. application
  20. end
  21. end
  22. def application
  23. eat(:lparen)
  24. if @current_token.type == :identifier && @current_token.value == 'define'
  25. eat(:identifier)
  26. name = identifier
  27. value = expr
  28. p @current_token
  29. eat(:rparen)
  30. return AST::Definition.new(name, value)
  31. end
  32. expression = expr
  33. args = Array.new
  34. until @current_token.type == :rparen
  35. args << expr
  36. end
  37. eat(:rparen)
  38. AST::Application.new(expression, args)
  39. end
  40. def identifier
  41. identifier = eat(:identifier)
  42. AST::Identifier.new(identifier.value)
  43. end
  44. def constant
  45. case @current_token.type
  46. when :number
  47. token = eat(:number)
  48. AST::Number.new(token.value.to_f)
  49. when :string
  50. token = eat(:string)
  51. AST::String.new(token.value)
  52. end
  53. end
  54. def eat(type)
  55. if @current_token.type == type
  56. token = @current_token
  57. @current_token = @lexer.get_next_token
  58. token
  59. else
  60. raise "Expected #{type} but got #{@current_token.type}"
  61. end
  62. end
  63. end
  64. end