Class: Lisp::Format::Parser

Inherits:
Object show all
Defined in:
lib/carat/lisp-format.rb

Overview

Given a lexer, parses the tokens it constructs. It works, quite simply, by maintaining a stack of nesting levels and directives/tokens are added to the current stack level. When a directive removes a level of nesting the previous level’s last directive gets connected, using Directive#connect.

Instance Method Summary collapse

Constructor Details

#initialize(lexer) ⇒ Parser

Create a Parser, given a Lexer, lexer.



377
378
379
# File 'lib/carat/lisp-format.rb', line 377

def initialize(lexer)
  @lexer = lexer
end

Instance Method Details

#parseObject

Do the actual parsing of the tokens. Returns a list of the top-level tokens to run.



383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
# File 'lib/carat/lisp-format.rb', line 383

def parse
  stacks = [[]]
  level = 0
  until (token = @lexer.next_token(stacks[level>0?level-1:0].last)).nil?
    directive = token[0]
    nesting = token[1]
    ntop = stacks[level].last.nil? ?
      directive : stacks[level].last.join(directive)
    stacks[level] << directive
    if nesting > 0
      stacks.push []
      level += 1
    elsif nesting < 0
      directives = stacks.pop
      level -= 1
      stacks[level].last.connect directives
    end
  end
  if stacks.size > 1
    raise SyntaxError.new(stacks[-2].last.pos), 'unterminated directive'
  end
  return stacks[0]
end