class Logicality::Parser::SimpleParser

Parser that takes in a lexer and can take its parsed grammar and turn it into an abstract syntax tree.

Constants

BINARY_TYPES

Attributes

current_token[R]
lexer[R]

Public Class Methods

new(lexer) click to toggle source
# File lib/logicality/parser/simple_parser.rb, line 17
def initialize(lexer)
  @lexer = lexer

  @current_token = lexer.next_token

  raise ArgumentError, 'Lexer must contain at least one token' if @current_token.nil?
end

Public Instance Methods

parse() click to toggle source
# File lib/logicality/parser/simple_parser.rb, line 25
def parse
  expr
end

Private Instance Methods

eat(token_type) click to toggle source
# File lib/logicality/parser/simple_parser.rb, line 42
def eat(token_type)
  if current_token.type == token_type
    @current_token = lexer.next_token
  else
    error
  end

  nil
end
error() click to toggle source
# File lib/logicality/parser/simple_parser.rb, line 38
def error
  raise ArgumentError, 'Invalid parser syntax'
end
expr() click to toggle source
# File lib/logicality/parser/simple_parser.rb, line 75
def expr
  node = factor

  loop do
    break unless current_token && BINARY_TYPES.include?(current_token.type)

    token = current_token

    if token.type == Lexer::Token::Type::AND_OP
      eat(Lexer::Token::Type::AND_OP)
    elsif token.type == Lexer::Token::Type::OR_OP
      eat(Lexer::Token::Type::OR_OP)
    end

    node = Ast::BinaryOperatorNode.new(node, token, factor)
  end

  node
end
factor() click to toggle source
# File lib/logicality/parser/simple_parser.rb, line 52
def factor
  token = current_token

  if current_token.type == Lexer::Token::Type::VALUE
    eat(Lexer::Token::Type::VALUE)

    Ast::ValueOperandNode.new(token)
  elsif current_token.type == Lexer::Token::Type::LEFT_PAREN
    eat(Lexer::Token::Type::LEFT_PAREN)
    node = expr
    eat(Lexer::Token::Type::RIGHT_PAREN)

    node
  elsif current_token.type == Lexer::Token::Type::NOT_OP
    eat(Lexer::Token::Type::NOT_OP)
    node = factor

    Ast::UnaryOperatorNode.new(node, token)
  else
    raise ArgumentError, "Factor cannot determine what to do with: #{token}"
  end
end