Class: Rattler::Runtime::ExtendedPackratParser

Inherits:
PackratParser show all
Defined in:
lib/rattler/runtime/extended_packrat_parser.rb

Overview

ExtendedPackratParser implements the algorithm described by Alessandro Warth, James R. Douglass, and Todd Millstein for extending packrat parsing to support left-recursive grammars.

Author:

  • Jason Arhart

Direct Known Subclasses

Grammar::GrammarParser

Defined Under Namespace

Classes: Head, LR

Instance Attribute Summary

Attributes inherited from Parser

#source

Instance Method Summary collapse

Methods inherited from RecursiveDescentParser

#match, #method_missing, #respond_to?

Methods included from Grammar::GrammarDSL

included

Methods included from ParserHelper

#select_captures

Methods inherited from Parser

#fail, #fail!, #fail_parse, #failure, #failure?, #parse, #parse!, parse!, #parse_fully, #parse_fully!, parse_fully!, #pos, #pos=

Methods inherited from Util::Node

#==, #[], [], #attrs, #can_equal?, #child, #children, #each, #empty?, #eql?, #inspect, #method_missing, #name, #respond_to?, #same_contents?, #to_graphviz, #with_attrs, #with_attrs!, #with_children

Constructor Details

#initialize(source, options = {}) ⇒ ExtendedPackratParser

Create a new extended packrat parser to parse source.

Parameters:

  • source (String)

    the source to parse

  • options (Hash) (defaults to: {})

    a customizable set of options

Options Hash (options):

  • :tab_size (Int) — default: 8

    tab size to use to calculate column numbers



25
26
27
28
29
# File 'lib/rattler/runtime/extended_packrat_parser.rb', line 25

def initialize(source, options={})
  super
  @heads = {}
  @lr_stack = []
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class Rattler::Runtime::RecursiveDescentParser

Instance Method Details

#apply(rule_name) ⇒ Object Also known as: memoize_lr



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/rattler/runtime/extended_packrat_parser.rb', line 31

def apply(rule_name)
  start_pos = @scanner.pos
  if m = memo_lr(rule_name, start_pos)
    recall m, rule_name
  else
    lr = LR.new(false, rule_name, nil)
    @lr_stack.push lr
    m = inject_memo rule_name, start_pos, lr, start_pos
    result = eval_rule rule_name
    @lr_stack.pop
    if lr.head
      m.end_pos = @scanner.pos
      lr.seed = result
      lr_answer rule_name, start_pos, m
    else
      save m, result
    end
  end
end