From 501de3c0b47ad219cc1372466c98d3fd534c5556 Mon Sep 17 00:00:00 2001 From: Patrick Simianer Date: Tue, 10 Jun 2014 13:19:44 +0200 Subject: fix glue/pass-through rules --- grammar.rb | 6 +++--- parse.rb | 41 ++++++++++++++++++++++++----------------- 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 -- cgit v1.2.3