从此开始:
./backtrack_inline.rb:73: error: too few arguments to function 'backtrack'
如果您查看生成的代码,该backtrack
函数在第 29 行定义:
static VALUE backtrack(VALUE self, VALUE _ss, VALUE _s, VALUE _p, VALUE _mm, VALUE _ins, VALUE _del) { ... }
它有七个参数,原来的六个,加上VALUE self
它已被转换为Scan
类的方法。
在第 67 行对该函数的调用如下所示:
end = backtrack(ss, s, p, mm, ins, del);
它只有六个参数。RubyInline 不会将此转换为对对象方法的调用,它只是逐字复制它。这也是警告的makes integer from pointer without a cast
来源:函数定义已转换为 take VALUE
s,但您使用原始类型进行调用。
错误消息说backtrack_inline.rb
由于生成代码的第 54 行上的指令,错误来自第 73 行:
# line 61 "./backtrack_inline.rb"
这基本上告诉编译器“重置”其行和文件值以查找错误,并将下一行 (55) 视为文件中的第 61 行./backtrack_inline.rb
。实际的行是 67, 12 在 55 之前,但是编译器将它报告为 73, 12 在 61 之前(它被重置的值)并且来自不同的文件。这种技术在这种情况下实际上不起作用,因为它没有考虑 RubyInline 添加的额外行。源代码中的实际行是 69。
一个简单的解决方法是将backtrack
函数的定义更改为只是一个 C 函数,而不是将其作为方法添加到对象上。更改builder.c
为builder.prefix
(在 Ruby 文件的第 38 行)。backtrack
如果您希望在 Ruby 中作为对象上的方法可用,这将不起作用。如果是这种情况,您可能需要创建另一个函数作为方法,然后包装“真实”回溯函数。
接下来看
./backtrack_inline.rb:67: error: lvalue required as unary '&' operand
这实际上是指生成代码的第 61 行,如下所示:
char* s = StringValuePtr(rb_iv_get(self, "@seq"));
StringValuePtr
是一个宏,定义为:
#define StringValue(v) rb_string_value(&(v))
这就是&
in 的lvalue required as unary '&' operand
来源。您需要添加一个局部变量作为左值:
VALUE seq = rb_iv_get(self, "@seq");
char* s = StringValuePtr(seq);
就我而言(Mac OS X Snow Leopard、Ruby 1.9.3-p0、RubyInline 3.11.0),这两个更改使脚本运行时没有错误,但发出警告:
backtrack_inline.rb:47: warning: implicit conversion shortens 64-bit value into a 32-bit value
这实际上是指 ruby 文件的第 46 行:
return (s - ss) - 1;
s
和ss
是char *
,即 64 位指针(在这台机器上),函数的返回类型是int
- 32 位。添加显式强制转换解决了这个问题:
return (int)((s - ss) - 1);
它现在运行干净:
ruby-inline $ ruby backtrack_inline.rb
14
ruby-inline $
(我希望 14 是正确的答案!)
这是具有这些更改的脚本版本。