在几天前考虑了一下之后,没有提出任何值得发表的内容,我现在回到它,并提出了一些我喜欢的语法,因为它几乎像python:
macro PrintMacro: syntax: "print", oneOrMore(Var(), name='vars') return Printnl(vars, None)
- 使所有宏“关键字”看起来像创建python对象(
Var()
而不是simpleVar
) - 将元素名称作为“关键字参数”传递给我们要为其命名的项目。仍然很容易在解析器中找到所有名称,因为无论如何都需要以某种方式解释此语法定义以填充宏类语法变量。
需要进行转换以填充结果宏类的语法变量。
内部语法表示也可能看起来相同:
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) )
我认为这将提供一个相当灵活的系统。主要优点:
- 易于学习(看起来像标准python)
- 易于解析(类似于标准python的解析)
- 可选项目很容易处理,因为您可以
None
在处理程序中使用默认参数 - 灵活使用命名项:
- 如果不需要,则无需命名任何项目,因为语法树始终会传入。
- 您可以在大型宏定义中命名任何子表达式,因此很容易挑选出您感兴趣的特定内容
- 如果要向宏结构添加更多功能,可以轻松扩展。例如
Several("abc", min=3, max=5, name="a")
。我认为这也可以用于将默认值添加到可选元素,例如Optional("step", Var(), name="step", default=1)
。
我不确定带有“ quote:”和“ $”的quote /
unquote语法,但是需要一些语法,因为如果您不必手动编写语法树,它将使工作变得更加轻松。要求(或只是允许?)“
$”括号可能是个好主意,因此,如果需要,您可以插入更复杂的语法部分。像
$(Stmt(a, b, c))。
ToMacro看起来像这样:
# macro definitionmacro 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 classclass 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, ')']]
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)