Class: RLTK::Parser::State

Inherits:
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<Token>)

    Tokens that represent this state.

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

    Items that make up this state.



1419
1420
1421
1422
1423
# File 'lib/rltk/parser.rb', line 1419

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

Instance Attribute Details

#actionsArray<Action> (readonly)

Returns Action objects that represent the actions that should be taken when various inputs are observed.

Returns:

  • (Array<Action>)

    Action objects that represent the actions that should be taken when various inputs are observed.



1413
1414
1415
# File 'lib/rltk/parser.rb', line 1413

def actions
  @actions
end

#idInteger

Returns State’s ID.

Returns:



1407
1408
1409
# File 'lib/rltk/parser.rb', line 1407

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.



1410
1411
1412
# File 'lib/rltk/parser.rb', line 1410

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)


1432
1433
1434
# File 'lib/rltk/parser.rb', line 1432

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

#add_reduction(production_id) ⇒ void

This method returns an undefined value.

Add a Reduce action to the state.

Parameters:

  • production_id (Integer)

    ID of production to add to this state.



1441
1442
1443
1444
1445
1446
# File 'lib/rltk/parser.rb', line 1441

def add_reduction(production_id)
  action = Reduce.new(production_id)
  
  # 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.



1449
1450
1451
# File 'lib/rltk/parser.rb', line 1449

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.



1457
1458
1459
# File 'lib/rltk/parser.rb', line 1457

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)


1466
1467
1468
1469
1470
1471
1472
# File 'lib/rltk/parser.rb', line 1466

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)


1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
# File 'lib/rltk/parser.rb', line 1482

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.



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

def each
  @items.each {|item| yield item}
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.



1519
1520
1521
1522
1523
1524
1525
# File 'lib/rltk/parser.rb', line 1519

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.



1533
1534
1535
# File 'lib/rltk/parser.rb', line 1533

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