在几天前考虑了一下之后,没有提出任何值得发表的内容,我现在回到它,并提出了一些我喜欢的语法,因为它几乎像python:
macro PrintMacro:
Syntax:
"print", OneOrMore(Var(), name='vars')
return Printnl(vars, None)
需要进行转换以填充结果宏类的语法变量。
内部语法表示也可能看起来相同:
class PrintMacro(Macro):
Syntax = 'print', OneOrMore(Var(), name='vars')
...
像OneOrMore
这样的内部语法类将遵循此模式以允许子项目和可选名称:
class MacroSyntaxElement(object):
def __init__(self, *p, name=None):
self.subelements = p
self.name = name
当宏匹配时,您只需收集所有具有名称的项目并将它们作为关键字参数传递给处理程序函数:
class Macro():
...
def parse(self, ...):
Syntaxtree = []
nameditems = {}
# parse, however this is done
# store all elements that have a name as
# nameditems[name] = parsed_element
self.handle(Syntaxtree, **nameditems)
然后将定义处理程序函数,如下所示:
class PrintMacro(Macro):
...
def handle(self, Syntaxtree, vars):
return Printnl(vars, None)
我添加了语法树作为始终传递的第一个参数,因此,如果您只想在语法树上做非常基本的事情,则不需要任何命名项。
另外,如果您不喜欢装饰器,为什么不像“基类”那样添加宏类型呢?IfMacro
然后将如下所示:
macro IfMacro(MultiLine):
Syntax:
Group("if", Var(), ":", Var(), name='if_')
ZeroOrMore("elif", Var(), ":", Var(), name='elifs')
Optional("else", Var(name='elseBody'))
return If(
[(cond, Stmt(body)) for keyword, cond, colon, body in [if_] + elifs],
None if elseBody is None else Stmt(elseBody)
)
并在内部表示形式中:
class IfMacro(MultiLineMacro):
Syntax = (
Group("if", Var(), ":", Var(), name='if_'),
ZeroOrMore("elif", Var(), ":", Var(), name='elifs'),
Optional("else", Var(name='elseBody'))
)
def handle(self, Syntaxtree, if_=None, elifs=None, elseBody=None):
# Default parameters in case there is no such named item.
# In this case this can only happen for 'elseBody'.
return If(
[(cond, Stmt(body)) for keyword, cond, body in [if_] + elifs],
None if elseNody is None else Stmt(elseBody)
)
我认为这将提供一个相当灵活的系统。主要优点:
我不确定带有“ quote:”和“ $”的quote / unquote语法,但是需要一些语法,因为如果您不必手动编写语法树,它将使工作变得更加轻松。要求(或只是允许?)“ $”括号可能是个好主意,因此,如果需要,您可以插入更复杂的语法部分。像$(Stmt(a, b, c))
。
ToMacro看起来像这样:
# macro deFinition
macro ToMacro(Partial):
Syntax:
Var(name='start'), "to", Var(name='end'), Optional("inclusive", name='inc'), Optional("step", Var(name='step'))
if step == None:
step = quote(1)
if inclusive:
return quote:
xrange($(start), $(end)+1, $(step))
else:
return quote:
xrange($(start), $(end), $(step))
# resulting macro class
class ToMacro(PartialMacro):
Syntax = Var(name='start'), "to", Var(name='end'), Optional("inclusive", name='inc'), Optional("step", Var(name='step'))
def handle(Syntaxtree, start=None, end=None, inc=None, step=None):
if step is None:
step = Number(1)
if inclusive:
return ['xrange', ['(', start, [end, '+', Number(1)], step, ')']]
return ['xrange', ['(', start, end, step, ')']]