Class: RLTK::Parser::State

Inherits:
Object
  • Object
show all
Defined in:
lib/rltk/parser.rb

Overview

The State class is used to represent sets of items and actions to be used during parsing.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(tokens, items = []) ⇒ State

Instantiate a new State object.

Parameters:

  • tokens (Array<Symbol>)

    Tokens that represent this state

  • items (Array<CFG::Item>) (defaults to: [])

    Items that make up this state



1507
1508
1509
1510
1511
# File 'lib/rltk/parser.rb', line 1507

def initialize(tokens, items = [])
  @id      = nil
  @items   = items
  @actions = tokens.inject(Hash.new) { |h, t| h[t] = Array.new; h }
end

Instance Attribute Details

#actionsHash{Symbol => Array<Action>} (readonly)

Returns Maps lookahead symbols to actions.

Returns:

  • (Hash{Symbol => Array<Action>})

    Maps lookahead symbols to actions



1501
1502
1503
# File 'lib/rltk/parser.rb', line 1501

def actions
  @actions
end

#idInteger

Returns State’s ID.

Returns:

  • (Integer)

    State’s ID.



1495
1496
1497
# File 'lib/rltk/parser.rb', line 1495

def id
  @id
end

#itemsArray<CFG::Item> (readonly)

Returns Item objects that comprise this state.

Returns:

  • (Array<CFG::Item>)

    Item objects that comprise this state



1498
1499
1500
# File 'lib/rltk/parser.rb', line 1498

def items
  @items
end

Instance Method Details

#==(other) ⇒ Boolean

Compare one State to another. Two States are equal if they have the same items or, if the items have been cleaned, if the States have the same ID.

Parameters:

  • other (State)

    Another State to compare to

Returns:

  • (Boolean)


1520
1521
1522
# File 'lib/rltk/parser.rb', line 1520

def ==(other)
  if self.items and other.items then self.items == other.items else self.id == other.id end
end

#add_reduction(production) ⇒ void

This method returns an undefined value.

Add a Reduce action to the state.

Parameters:

  • production (Production)

    Production used to perform the reduction



1529
1530
1531
1532
1533
1534
# File 'lib/rltk/parser.rb', line 1529

def add_reduction(production)
  action = Reduce.new(production)

  # Reduce actions are not allowed for the ERROR terminal.

  @actions.each { |k, v| if CFG::is_terminal?(k) and k != :ERROR then v << action end }
end

#append(item) ⇒ Object Also known as: <<

Parameters:

  • item (CFG::Item)

    Item to add to this state.



1537
1538
1539
# File 'lib/rltk/parser.rb', line 1537

def append(item)
  if item.is_a?(CFG::Item) and not @items.include?(item) then @items << item end
end

#cleanvoid

This method returns an undefined value.

Clean this State by removing the list of CFG::Item objects.



1545
1546
1547
# File 'lib/rltk/parser.rb', line 1545

def clean
  @items = nil
end

#close(productions) ⇒ vod

Close this state using productions.

Parameters:

  • productions (Array<CFG::Production>)

    Productions used to close this state.

Returns:

  • (vod)


1554
1555
1556
1557
1558
1559
1560
# File 'lib/rltk/parser.rb', line 1554

def close(productions)
  self.each do |item|
    if (next_symbol = item.next_symbol) and CFG::is_nonterminal?(next_symbol)
      productions[next_symbol].each { |p| self << p.to_item }
    end
  end
end

#conflict_on?(sym) ⇒ :SR, ...

Checks to see if there is a conflict in this state, given a input of sym. Returns :SR if a shift/reduce conflict is detected and :RR if a reduce/reduce conflict is detected. If no conflict is detected nil is returned.

Parameters:

  • sym (Symbol)

    Symbol to check for conflicts on.

Returns:

  • (:SR, :RR, nil)


1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
# File 'lib/rltk/parser.rb', line 1570

def conflict_on?(sym)

  reductions = 0
  shifts   = 0

  @actions[sym].each do |action|
    if action.is_a?(Reduce)
      reductions += 1

    elsif action.is_a?(Shift)
      shifts += 1

    end
  end

  if shifts == 1 and reductions > 0
    :SR
  elsif reductions > 1
    :RR
  else
    nil
  end
end

#eachvoid

This method returns an undefined value.

Iterate over the state’s items.



1597
1598
1599
1600
1601
1602
1603
# File 'lib/rltk/parser.rb', line 1597

def each
  current_item = 0
  while current_item < @items.count
    yield @items.at(current_item)
    current_item += 1
  end
end

#on(symbol, action) ⇒ void

This method returns an undefined value.

Specify an Action to perform when the input token is symbol.

Parameters:

  • symbol (Symbol)

    Symbol to add action for.

  • action (Action)

    Action for symbol.



1611
1612
1613
1614
1615
1616
1617
# File 'lib/rltk/parser.rb', line 1611

def on(symbol, action)
  if @actions.key?(symbol)
    @actions[symbol] << action
  else
    raise ParserConstructionException, "Attempting to set action for token (#{symbol}) not seen in grammar definition."
  end
end

#on?(symbol) ⇒ Array<Action>

Returns that actions that should be taken when the input token is symbol.

Parameters:

  • symbol (Symbol)

    Symbol we want the actions for.

Returns:

  • (Array<Action>)

    Actions that should be taken.



1625
1626
1627
# File 'lib/rltk/parser.rb', line 1625

def on?(symbol)
  @actions[symbol].clone
end