summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Simianer <p@simianer.de>2014-06-10 13:19:44 +0200
committerPatrick Simianer <p@simianer.de>2014-06-10 13:19:44 +0200
commit501de3c0b47ad219cc1372466c98d3fd534c5556 (patch)
treefaf84bfc1cb6d43ccbacd996815a8895eb705a40
parent1298b37784247d6de486814838b07ddcf69cd970 (diff)
fix glue/pass-through rules
-rw-r--r--grammar.rb6
-rw-r--r--parse.rb41
2 files changed, 27 insertions, 20 deletions
diff --git a/grammar.rb b/grammar.rb
index 003512c..ea16425 100644
--- a/grammar.rb
+++ b/grammar.rb
@@ -114,16 +114,16 @@ class Grammar
def add_glue_rules
@rules.map { |r| r.lhs.symbol }.select { |s| s != 'S' }.uniq.each { |symbol|
- @rules << Rule.new(NT.new('S'), [NT.new(symbol)])
+ @rules << Rule.new(NT.new('S'), [NT.new(symbol, 0)], [NT.new(symbol, 0)], [0])
@startn << @rules.last
- @rules << Rule.new(NT.new('S'), [NT.new('S'), NT.new('X')])
+ @rules << Rule.new(NT.new('S'), [NT.new('S', 0), NT.new('X'), 1], [NT.new('S', 0), NT.new('X'), 1], [0, 1])
@startn << @rules.last
}
end
def add_pass_through_rules s
s.each { |word|
- @rules << Rule.new(NT.new('X'), [T.new(word)])
+ @rules << Rule.new(NT.new('X'), [T.new(word)], [T.new(word)])
@flat << @rules.last
}
end
diff --git a/parse.rb b/parse.rb
index 24b98c6..887a64b 100644
--- a/parse.rb
+++ b/parse.rb
@@ -31,27 +31,32 @@ class Chart
end
class Item < Grammar::Rule
- attr_accessor :dot
+ attr_accessor :spans, :dot
def initialize rule_or_item, left, right, dot
- @lhs = Grammar::NT.new rule_or_item.lhs.symbol
- @lhs.span = Grammar::Span.new left, right
+ @lhs = Grammar::NT.new(rule_or_item.lhs.symbol, rule_or_item.lhs.index)
+ @spans = {}
+ @spans[0] = [left, right]
@rhs = []
- rule_or_item.rhs.each { |x|
+ rule_or_item.rhs.each_with_index { |x,i|
if x.class == Grammar::T
@rhs << Grammar::T.new(x.word)
end
if x.class == Grammar::NT
- @rhs << Grammar::NT.new(x.symbol)
- @rhs.last.span = Grammar::Span.new x.span.left, x.span.right
+ @rhs << Grammar::NT.new(x.symbol, x.index)
+ begin
+ @spans[i] = rule_or_item.spans[i].dup
+ rescue
+ @spans[i] = [-1, -1]
+ end
end
}
@dot = dot
- @e = rule_or_item.e
+ @target = rule_or_item.target
end
def to_s
- "#{lhs} -> #{rhs.map{|i|i.to_s}.insert(@dot,'*').join ' '} [dot@#{@dot}] [arity=#{arity}] (#{@lhs.span.left}, #{@lhs.span.right}) ||| #{@e}"
+ "#{lhs} -> #{rhs.map{|i|i.to_s}.insert(@dot,'*').join ' '} [dot@#{@dot}] [arity=#{arity}] (#{@spans[0][0]}, #{@spans[0][1]}) ||| #{@target.map{|x|x.to_s}.join ' '}"
end
end
@@ -67,10 +72,10 @@ end
def scan item, input, limit, passive_chart
while item.rhs[item.dot].class == Grammar::T
- return false if item.lhs.span.right==limit
- if item.rhs[item.dot].word == input[item.lhs.span.right]
+ return false if item.spans[0][1]==limit
+ if item.rhs[item.dot].word == input[item.spans[0][1]]
item.dot += 1
- item.lhs.span.right += 1
+ item.spans[0][1] += 1
else
return false
end
@@ -111,18 +116,19 @@ def parse input, n, active_chart, passive_chart, grammar
advanced = false
visit(1, i, j, 1) { |k,l|
if passive_chart.has active_item.rhs[active_item.dot].symbol, k, l
- if k == active_item.lhs.span.right
- new_item = Item.new active_item, active_item.lhs.span.left, l, active_item.dot+1
- new_item.rhs[new_item.dot-1].span = Grammar::Span.new k, l
+ if k == active_item.spans[0][1]
+ new_item = Item.new active_item, active_item.spans[0][0], l, active_item.dot+1
+ new_item.spans[new_item.dot-1][0] = k
+ new_item.spans[new_item.dot-1][1] = l
if scan new_item, input, j, passive_chart
if new_item.dot == new_item.rhs.size
- if new_item.lhs.span.left == i && new_item.lhs.span.right == j
+ if new_item.spans[0][0] == i && new_item.spans[0][1] == j
new_symbols << new_item.lhs.symbol if !new_symbols.include? new_item.lhs.symbol
passive_chart.add new_item, i, j
advanced = true
end
else
- if new_item.lhs.span.right+(new_item.rhs.size-(new_item.dot)) <= j
+ if new_item.spans[0][1]+(new_item.rhs.size-(new_item.dot)) <= j
active_chart.at(i,j) << new_item
advanced = true
end
@@ -143,7 +149,8 @@ def parse input, n, active_chart, passive_chart, grammar
next if active_item.rhs[active_item.dot].class!=Grammar::NT
if active_item.rhs[active_item.dot].symbol == s
new_item = Item.new active_item, i, j, active_item.dot+1
- new_item.rhs[new_item.dot-1].span = Grammar::Span.new i, j
+ new_item.spans[new_item.dot-1][0] = i
+ new_item.spans[new_item.dot-1][1] = j
if new_item.dot==new_item.rhs.size
new_symbols << new_item.lhs.symbol if !new_symbols.include? new_item.lhs.symbol
passive_chart.add new_item, i, j