Class: Ariel::Rule

Inherits:
Object
  • Object
show all
Defined in:
lib/ariel/rule.rb

Overview

A rule contains an array of landmarks (each of which is an array of individual landmark features. This landmark array is accessible through Rule#landmarks. A Rule also has a direction :forward or :back, which determines whether it is applied from the end or beginning of a tokenstream.

Constant Summary collapse

@@RuleMatchData =
Struct.new(:token_loc, :type)

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(direction, landmarks = []) ⇒ Rule

A rule’s direction can be :back or :forward, which determines whether it is applied from the start of end of the TokenStream. The landmark array contains an array for each landmark, which consists of one or more features. e.g. Rule.new(:forward, [[:anything, “Example”], [“Test”]]).

Raises:

  • (ArgumentError)


15
16
17
18
19
# File 'lib/ariel/rule.rb', line 15

def initialize(direction, landmarks=[])
  @landmarks=landmarks
  raise(ArgumentError, "Not a valid direction") unless [:forward, :back].include?(direction)
  @direction=direction
end

Instance Attribute Details

#directionObject

Returns the value of attribute direction.



8
9
10
# File 'lib/ariel/rule.rb', line 8

def direction
  @direction
end

#landmarksObject

Returns the value of attribute landmarks.



8
9
10
# File 'lib/ariel/rule.rb', line 8

def landmarks
  @landmarks
end

Instance Method Details

#==(rule) ⇒ Object Also known as: eql?

Two rules are equal if they have the same list of landmarks and the same direction



23
24
25
# File 'lib/ariel/rule.rb', line 23

def ==(rule)
  return ((self.landmarks == rule.landmarks) && self.direction==rule.direction)
end

#apply_to(tokenstream) {|md| ... } ⇒ Object

Given a TokenStream and a rule, applies the rule on the stream and returns nil if the match fails and the token_loc if the match succeeds. Yields a RuleMatchData Struct with accessors token_loc (the position of the match in the stream) and type if a block is given. type is nil if the TokenStream has no label, :perfect if all tokens up to the labeled token are consumed, :early if the rule’s final position is before the labeled token, and :late if it is after. The returned token_loc is the position in the stream as it was passed in. That is, the token_loc is always from the left of the given stream whether it is in a reversed state or not.

Yields:

  • (md)


68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/ariel/rule.rb', line 68

def apply_to(tokenstream)
  if tokenstream.reversed?
    target=tokenstream if @direction==:back
    target=tokenstream.reverse if @direction==:forward
  elsif not tokenstream.reversed?
    target=tokenstream if @direction==:forward
    target=tokenstream.reverse if @direction==:back
  end
  target.rewind #rules are applied from the beginning of the stream
  @landmarks.each do |landmark|
    unless target.skip_to(*landmark)
      return nil
    end
  end
  token_loc=target.cur_pos
  if @direction==:back && !tokenstream.reversed?
    token_loc = tokenstream.reverse_pos(token_loc) #Return position from left of given stream
  end
  md = @@RuleMatchData.new(token_loc)
  if target.label_index
    idx = target.label_index
    md.type = :perfect if token_loc == idx
    md.type = :early if token_loc < idx
    md.type = :late if token_loc > idx
  end
  yield md if block_given?
  return token_loc
end

#deep_cloneObject



37
38
39
# File 'lib/ariel/rule.rb', line 37

def deep_clone
  Marshal::load(Marshal.dump(self))
end

#generalise_feature(landmark_index, feature_index = 0) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
# File 'lib/ariel/rule.rb', line 41

def generalise_feature(landmark_index, feature_index=0)
  feature=self.landmarks[landmark_index][feature_index]
  alternates=[]
  Wildcards.matching(feature) do |wildcard|
    r=self.deep_clone
    r.landmarks[landmark_index][feature_index]=wildcard
    alternates << r
    yield r if block_given?
  end
  return alternates
end

#hashObject



28
29
30
# File 'lib/ariel/rule.rb', line 28

def hash
  [@landmarks, @direction].hash
end

#matches(tokenstream, *types) ⇒ Object

Returns true or false depending on if the match of this rule on the given tokenstream is of any of the given types (could be a combination of :perfect, :early, :fail and :late). Only valid on streams with labels

Raises:

  • (ArgumentError)


100
101
102
103
104
105
106
107
108
109
110
# File 'lib/ariel/rule.rb', line 100

def matches(tokenstream, *types)
  raise ArgumentError, "No match types given" if types.empty?
  match = nil
  apply_to(tokenstream) {|md| match=md.type}
  match = :fail if match.nil?
  if types.include? match
    return true
  else
    return false
  end
end

#partial(range) ⇒ Object

Returns a rule that contains a given range of



33
34
35
# File 'lib/ariel/rule.rb', line 33

def partial(range)
  return Rule.new(@direction, @landmarks[range])
end

#wildcard_countObject

Returns the number of wildcards included as features in the list of rule landmarks.



55
56
57
# File 'lib/ariel/rule.rb', line 55

def wildcard_count
  @landmarks.flatten.select {|feature| feature.kind_of? Symbol}.size
end