class TaskJuggler::TextParser::State

This State objects describes a state of the TextParser FSM. A State captures the position in the syntax description that the parser is currently at. A position is defined by the Rule, the Pattern and the index of the current token of that Pattern. An index of 0 means, we've just read the 1st token of the pattern. States which have no Pattern describe the start of rule. The parser has not yet identified the first token, so it doesn't know the Pattern yet.

The actual data of a State is the list of possible StateTransitions to other states and a boolean flag that specifies if Reduce operations are valid for this State or not. The transitions are hashed by the token that would trigger this transition.

Attributes

index[R]
noReduce[RW]
pattern[R]
rule[R]
transitions[R]

Public Class Methods

new(rule, pattern = nil, index = 0) click to toggle source
# File lib/taskjuggler/TextParser/State.rb, line 84
def initialize(rule, pattern = nil, index = 0)
  @rule = rule
  @pattern = pattern
  @index = index
  # Starting states are always reduceable. Other states may or may not be
  # reduceable. For now, we assume they are not.
  @noReduce = !pattern.nil?

  @transitions = {}
end

Public Instance Methods

addTransition(token, nextState, stateStack, loopBack) click to toggle source

This method adds the actual StateTransition to this State.

# File lib/taskjuggler/TextParser/State.rb, line 110
def addTransition(token, nextState, stateStack, loopBack)
  tr = StateTransition.new(token, nextState, stateStack, loopBack)
  if @transitions.include?(tr.tokenType)
    raise "Ambiguous transition for #{tr.tokenType} in \n#{self}\n" +
          "The following transition both match:\n" +
          "  #{tr}\n  #{@transitions[tr.tokenType]}"
  end
  @transitions[tr.tokenType] = tr
end
addTransitions(states, rules) click to toggle source

Complete the StateTransition list. We can only call this function after all State objects for the syntax have been created. So we can't make this part of the constructor.

# File lib/taskjuggler/TextParser/State.rb, line 98
def addTransitions(states, rules)
  if @pattern
    # This is an normal state node.
    @pattern.addTransitionsToState(states, rules, [], self,
                                   @rule, @index + 1, false)
  else
    # This is a start node.
    @rule.addTransitionsToState(states, rules, [], self, false)
  end
end
expectedTokens() click to toggle source

Return a comma separated list of token strings that would trigger transitions for this State.

# File lib/taskjuggler/TextParser/State.rb, line 135
def expectedTokens
  tokens = []
  @transitions.each_key do |t|
    tokens << "#{t.is_a?(String) ? "'#{t}'" : ":#{t}"}"
  end
  tokens
end
to_s(short = false) click to toggle source

Convert the State data into a human readable form. Used for debugging only.

# File lib/taskjuggler/TextParser/State.rb, line 145
def to_s(short = false)
  if short
    if @pattern
      str = "#{rule.name} " +
            "#{rule.patterns.index(@pattern)} #{@index}"
    else
      str = "#{rule.name} (Starting Node)"
    end
  else
    if @pattern
      str = "=== State: #{rule.name} " +
            "#{rule.patterns.index(@pattern)} #{@index}" +
            " #{@noReduce ? '' : '(R)'}" +
            " #{'=' * 40}\nPattern: #{@pattern}\n"
    else
      str = "=== State: #{rule.name} (Starting Node) #{'=' * 30}\n"
    end

    @transitions.each do |type, target|
      targetStr = target ? target.to_s : "<EOF>"
      str += "  #{type.is_a?(String) ? "'#{type}'" : ":#{type}"}" +
             " => #{targetStr}\n"
    end
    str += "#{'=' * 76}\n"
  end
  str
end
transition(token) click to toggle source

Find the transition that matches token.

# File lib/taskjuggler/TextParser/State.rb, line 121
def transition(token)
  if token[0] == :ID
    # The scanner cannot differentiate between IDs and literals that look
    # like IDs. So we look for literals first and then for IDs.
    @transitions[token[1]] || @transitions[:ID]
  elsif token[0] == :LITERAL
    @transitions[token[1]]
  else
    @transitions[token[0]]
  end
end