Class: Lisp::Format::Parser
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
-
#initialize(lexer) ⇒ Parser
constructor
Create a Parser, given a Lexer,
lexer
. -
#parse ⇒ Object
Do the actual parsing of the tokens.
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
#parse ⇒ Object
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 |