Class: Platform::IEL::SexpParser

Inherits:
Object
  • Object
show all
Defined in:
lib/introhive_expression_language/iel/sexp_parser.rb

Defined Under Namespace

Classes: Lexer, Node, ParseContext, ParseError, UnexpectedTokenError

Class Method Summary collapse

Class Method Details

.parse(expr) ⇒ Object

Parse the given expression and return its AST. Raises SexpParser::ParseError if a syntax error is encountered.



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/introhive_expression_language/iel/sexp_parser.rb', line 20

def self.parse(expr)
  parse_context = ParseContext.new(expr)
  node_stack = [Node.new(:list, 0, [], parse_context)]
  Lexer.tokenize(expr.chars, 0, parse_context) do |token|
    case token.kind
    when :string_literal, :numeric_literal, :symbol, :boolean, :nan, :nil
      node_stack.last.value << token
    when :list_end
      raise UnexpectedTokenError, token if node_stack.size == 1
      value = node_stack.pop
      raise UnexpectedTokenError, token if value.nil?
      node_stack.last.value << value
    when :list_start
      node_stack.push(Node.new(:list, token.source, [], parse_context))
    when :comment
      # Do nothing
    else
      raise UnexpectedTokenError, token
    end
  end
  if node_stack.size != 1
    raise ParseError, 'Unexpected end of input'
  end

  # Remove containing list if there's only a single item results.
  if node_stack.first.value.size == 1
    node_stack = node_stack.first.value
  end

  node_stack.first
end