作者:Toby Miller 标签:DotNet

3854天前 (阅读:47981)
原文链接http://docs.codehaus.org/display/BOO/Syntactic+Macros
  boo 是在 .Net 下实现的一种类似 Python 语法的语言,和 Python(以及 IronPython) 不同的是,boo 其实是静态语言,利用“类型推断”(C# 3.0 也会提供)等技术,使得它看起来有和动态语言类似的语法。宏是我在 boo 语言中觉得最有趣的技术,虽然也使用和动态对象相似的复杂语法,不过,它是一种编译器扩展,所有动作发生在编译时,而不需要在运行时进行动态类型的创建,并且,它可以比较自由的创建语法结构,我觉得这种做法已经非常接近我在LINQ 未满中提到的自定义 DSL 的能力。所以翻译了这一篇 boo 官方网站上介绍自定义宏的文章,不过,我第一次翻译文章,有很多语句用的很僵硬,并且,有一两句话的意思我也拿不太准,如果你英文比较好的话,还是去看英文版好了。
  顺便说一下,Ruby 中有更简单的语法用来进行类的扩展等操作,不过那是动态语言特性,静态语言很难模拟。Python 中应该也有,不过我不熟悉,就不多说了。
                         (译者:梁利锋)

  语法构造宏允许你创建新的语言构造。点击链接察看 boo 语言里的内建宏。

  例如,我们可以模拟 VisualBasic 的 with 语句。

  现在有以下的代码:
fooInstanceWithReallyLongName = Foo()
fooInstanceWithReallyLongName.f1 = 100
fooInstanceWithReallyLongName.f2 = "abc"
fooInstanceWithReallyLongName.DoSomething()

  如果我们定义了“with”宏,我们就可以把它重新写为:
with fooInstanceWithReallyLongName:
    _f1 = 100
    _f2 = "abc"
    _DoSomething()

  在 boo 语言中,宏是一个实现了 Boo.Lang.Compiler.IAstMacro 接口的 CLI 对象。这些对象本身并没有任何魔法。他们只是简单的实现编译器所期望的接口。这意味着 boo 语言的宏可以使用任何 CLI 语言编写!

  在编译的时候,如果遇到一个未知的语法构造,就像上面的 with 语句,编译器就会查找正确的 IAstMacro 类,创建一个它的实例,并且使用这个实例去扩展宏。编译器通过简单的命名约定来识别这些类。类名前面部分必须使用宏的名字,而结尾为“Macro”后缀。另外,必须使用Pascal case命令约定。所以,在这里,这个类的名字必须为“WithMacro”。

  这里是实现我们的宏的代码:
import Boo.Lang.Compiler
import Boo.Lang.Compiler.Ast
import Boo.Lang.Compiler.Ast.Visitors

class WithMacro(AbstractAstMacro):

    private class NameExpander(DepthFirstTransformer):

        _inst as ReferenceExpression

        def constructor(inst as ReferenceExpression):
            _inst = inst

        override def OnReferenceExpression(node as ReferenceExpression):
            // if the name of the reference begins with '_'
            // then convert the reference to a member reference
            // of the provided instance
            if node.Name.StartsWith('_'):
                // create the new member reference and set it up
                mre = MemberReferenceExpression(node.LexicalInfo)
                mre.Name = node.Name[1:]
                mre.Target = _inst.CloneNode()

                // replace the original reference in the AST
                // with the new member-reference
                ReplaceCurrentNode(mre)

    override def Expand(macro as MacroStatement) as Statement:
        assert 1 == macro.Arguments.Count
        assert macro.Arguments[0] isa ReferenceExpression

        inst = macro.Arguments[0] as ReferenceExpression

        // convert all _<ref> to inst.<ref>
        block = macro.Block
        ne = NameExpander(inst)
        ne.Visit(block)
        return block

  一些解释过程是有顺序的(?)。在编译器管道解析一个源代码流为一个抽象语法树(AST)的分析阶段。一个和宏相对应的子树,将会传递给 Expand() 方法。Expand() 负责建立一个 AST 以替换原来的子树。

  这个和宏语句相对应的子树包含在宏语句参数中。

  一个宏语句有一个参数集合和一个 block。

  在这里,我们期望一个单独的参数:一个对象的引用。然后我们遍历这个 block 以寻找名称前缀为“_”的引用。无论何时当我们遇到一个,我们就把它替换成对相应成员的引用。

  这里有两个类直接和 AST 遍历有关:DepthFirstVisitor 和 DepthFirstTransformer。他们遍历 AST,为树上的每一个类型的元素调用适当的方法。在这个例子中,我们实现了 DepthFirstTransformer 的一个子类以方便查找和替换宏中 block 上的 ReferenceExpression 节点。

  你可以在examples/macros directory找到包括这个例子在内的一些宏的例子。

  一个自定义宏语法也在计划中。

内建宏

  下面是一些 boo 语言的内建宏的使用例子:
print "hello!"

assert x == true

debug "print debug message"

using file=File.OpenText(fname): //disposes of file when done
    print(file.ReadLine())

o1 = object()
lock o1:  //similar to "synchronized" in java
    pass


Hello! ebbkdag interesting ebbkdag site! I'm reall(非注册用户) 2013-3-13 18:15:13

Hello! ebbkdag interesting ebbkdag site! I'm really like it! Very, very ebbkdag good!

Very nice site!(非注册用户) 2013-3-13 18:15:23

Very nice site!

Hello! ebgeeec interesting ebgeeec site! I'm reall(非注册用户) 2013-3-13 18:15:27

Hello! ebgeeec interesting ebgeeec site! I'm really like it! Very, very ebgeeec good!

Very nice site!(非注册用户) 2013-3-13 18:15:39

Very nice site!

Hello! kfgdcke interesting kfgdcke site! I'm reall(非注册用户) 2013-4-17 13:30:05

Hello! kfgdcke interesting kfgdcke site! I'm really like it! Very, very kfgdcke good!

Very nice site!(非注册用户) 2013-4-17 13:30:28

Very nice site!

Hello! dkeggfg interesting dkeggfg site! I'm reall(非注册用户) 2013-4-17 13:30:33

Hello! dkeggfg interesting dkeggfg site! I'm really like it! Very, very dkeggfg good!

Very nice site!(非注册用户) 2013-4-17 13:30:41

Very nice site!

Way to use the internet to help people solve prleb(非注册用户) 2015-1-19 19:04:41

Way to use the internet to help people solve prleboms!