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



1487
1488
1489
1490
1491
# File 'lib/rltk/parser.rb', line 1487

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



1481
1482
1483
# File 'lib/rltk/parser.rb', line 1481

def actions
  @actions
end

#idInteger

Returns State’s ID.

Returns:

  • (Integer)

    State’s ID.



1475
1476
1477
# File 'lib/rltk/parser.rb', line 1475

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



1478
1479
1480
# File 'lib/rltk/parser.rb', line 1478

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)


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

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



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

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.



1517
1518
1519
# File 'lib/rltk/parser.rb', line 1517

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.



1525
1526
1527
# File 'lib/rltk/parser.rb', line 1525

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)


1534
1535
1536
1537
1538
1539
1540
# File 'lib/rltk/parser.rb', line 1534

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)


1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
# File 'lib/rltk/parser.rb', line 1550

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.



1577
1578
1579
1580
1581
1582
1583
# File 'lib/rltk/parser.rb', line 1577

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.



1591
1592
1593
1594
1595
1596
1597
# File 'lib/rltk/parser.rb', line 1591

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.



1605
1606
1607
# File 'lib/rltk/parser.rb', line 1605

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