12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879 |
- module Chervil
- class Parser def initialize(lexer)
- @lexer = lexer
- @tree = Array.new
- @current_token = @lexer.get_next_token
- end
-
- def parse
- until @current_token.type == :eof
- @tree << expr
- end
- @tree
- end
-
- def expr
- if [:string, :number, :boolean].include?(@current_token.type)
- constant
- elsif @current_token.type == :identifier
- identifier
- elsif @current_token.type == :lparen
- application
- else
- raise "Unexpected token #{@current_token.type}: #{@current_token.value}"
- end
- end
-
- def application
- eat(:lparen)
-
- if @current_token.type == :identifier && @current_token.value == 'define'
- eat(:identifier)
- name = identifier
- value = expr
- eat(:rparen)
- return AST::Definition.new(name, value)
- end
-
- expression = expr
-
- args = Array.new
- until @current_token.type == :rparen
- args << expr
- end
-
- eat(:rparen)
-
- AST::Application.new(expression, args)
- end
-
- def identifier
- identifier = eat(:identifier)
- AST::Identifier.new(identifier.value)
- end
-
- def constant
- case @current_token.type
- when :number
- token = eat(:number)
- AST::Number.new(token.value.to_f)
- when :string
- token = eat(:string)
- AST::String.new(token.value)
- when :boolean
- token = eat(:boolean)
- AST::Boolean.new(token.value)
- end
- end
-
- def eat(type)
- if @current_token.type == type
- token = @current_token
- @current_token = @lexer.get_next_token
- token
- else
- raise "Expected #{type} but got #{@current_token.type}"
- end
- end
- end
- end
|