在SLY中,有一个编写计算器的示例(从calc.py
here复制):
from sly import Lexer
class CalcLexer(Lexer):
tokens = { NAME, NUMBER }
ignore = ' \t'
literals = { '=', '+', '-', '*', '/', '(', ')' }
# Tokens
NAME = r'[a-zA-Z_][a-zA-Z0-9_]*'
@_(r'\d+')
def NUMBER(self, t):
t.value = int(t.value)
return t
@_(r'\n+')
def newline(self, t):
self.lineno += t.value.count('\n')
def error(self, t):
print("Illegal character '%s'" % t.value[0])
self.index += 1
它看起来像是被窃听了,因为NAME
和NUMBER
在定义之前就被使用了。但是实际上,没有NameError
,并且这段代码执行得很好。这是怎么回事?在定义名称之前,何时可以引用名称
Python知道four kinds of direct name lookup:builtins / program global、模块全局、函数/闭包体和类体。
NAME
、NUMBER
在类主体中解析,因此受此类范围的规则约束类主体在namespace provided by the metaclass中求值,它可以实现名称查找的任意语义。具体地说,sly} 作为名称空间的
Lexer
是一个使用a ^{LexerMeta
类;此命名空间为未定义的名称创建新标记LexerMeta
还负责adding the ^{相关问题 更多 >
编程相关推荐