我是IronRuby的新手。我正在尝试将它与C#集成。
我创建了以下示例,它运行良好。
string rubyCode = @"
def function_111(test)
print 1
end
";
ScriptEngine engine = Ruby.CreateEngine();
ScriptScope scope = engine.CreateScope();
engine.Execute(rubyCode, scope);
dynamic sayHelloFun = scope.GetVariable("function_111");
sayHelloFun("test");
若你们看上面的代码,那个么我使用的是编译和执行代码的execute方法,但我只想解析代码,这意味着它的语法是否正确。
这怎么可能?
发布的链接似乎已经死了,搜索引擎缓存副本似乎正在腐烂,所以我将刮去帖子的剩余部分,并在下面进行解释。
您可以将IronRuby与动态语言运行时(DLR)一起使用来解析Ruby代码。步骤是:创建一个Ruby引擎实例,创建一个脚本源代码和单元,创建解析器并解析到AST,然后使用Walker遍历AST。
创建引擎
var runtime = IronRuby.Ruby.CreateRuntime();
var engine = runtime.GetEngine("rb");
创建源单元
var src = engine.CreateScriptSourceFromString(@"puts 'hello'"); // also: engine.CreateScriptSourceFromFile
var srcUnit = HostingHelpers.GetSourceUnit(src);
分析
var parser = new Parser();
var srcTreeUnit = parser.Parse(srcUnit, new RubyCompilerOptions(), ErrorSink.Default);
行走AST
var walker = new MyWalker();
walker.Walk(srcTreeUnit);
您需要对Walker类进行子类化,它有许多虚拟方法来处理访问AST中的各个节点。LinqPad查询中使用的一个看起来是这样的:
public class MyWalker : Walker
{
protected override void Walk(MethodCall node)
{
Console.WriteLine("Method call: " + node.MethodName);
base.Walk(node);
}
protected override void Walk(StringLiteral node)
{
Console.WriteLine("String Literal: " + node.GetMutableString().ToString());
base.Walk(node);
}
}
当你在上面生成的AST上运行这个助行器时,你会得到以下结果:
Method call: puts
String Literal: hello
我使用了LinqPad,添加了IronRuby 1.1.3 nuget包,并用上面的内容创建了一个LinqPad查询。