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



1444
1445
1446
1447
1448
# File 'lib/rltk/parser.rb', line 1444

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



1438
1439
1440
# File 'lib/rltk/parser.rb', line 1438

def actions
  @actions
end

#idInteger

Returns State’s ID.

Returns:

  • (Integer)

    State’s ID.



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

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



1435
1436
1437
# File 'lib/rltk/parser.rb', line 1435

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)


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

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



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

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.



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

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.



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

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)


1491
1492
1493
1494
1495
1496
1497
# File 'lib/rltk/parser.rb', line 1491

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)


1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
# File 'lib/rltk/parser.rb', line 1507

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.



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

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.



1548
1549
1550
1551
1552
1553
1554
# File 'lib/rltk/parser.rb', line 1548

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.



1562
1563
1564
# File 'lib/rltk/parser.rb', line 1562

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