[英]How to avoid printing a variable without using the say function in python sly?
So I am using a python package sly which has a lexer and parser class.所以我正在使用 python package sly ,它有一个词法分析器和解析器 class。 I am making my own programming language called NoobPy.
我正在制作自己的编程语言,称为 NoobPy。 So currently, the code will open test.noob and read each line and parse it.
所以目前,代码将打开 test.noob 并读取每一行并解析它。 Now, if I were to define a variable, let's say
x
, and just write x
in a line, it would print it, and I don't want that.现在,如果我要定义一个变量,比方说
x
,只需将x
写在一行中,它就会打印它,而我不希望这样。 I want it to print only if it's passed in the say
function which I made.我希望它仅在我制作的
say
中通过时才打印。 Lexer class莱克斯 class
class NoobpyLexer(Lexer):
tokens = {NUMBER, STRING, FALSE, TRUE, NAME, WHILE, IF, ELSE, SAY,
PLUS, MINUS, TIMES, DIVIDE, ASSIGN,
EQ, LT, LE, GT, GE, NEQ}
literals = {'(', ')', ':'}
# String containing ignored characters
ignore = ' \t'
# Regular expression rules for tokens
STRING = r'\".*?\"'
PLUS = r'\+'
MINUS = r'-'
TIMES = r'\*'
DIVIDE = r'/'
EQ = r'=='
NEQ = r'!='
ASSIGN = r'='
LE = r'<='
GE = r'>='
LT = r'<'
GT = r'>'
@_(r'\d+')
def NUMBER(self, t):
t.value = int(t.value)
return t
# @_(r'^((true$|false$)$)')
# def BOOL(self, t):
# return t
@_(r'true')
def TRUE(self, t):
return t
@_(r'false')
def FALSE(self, t):
return t
# Identifiers and keywords
NAME = r'\b(?!((true$|false$)$)\b)\w+' # [a-zA-Z_][a-zA-Z0-9_]*$
NAME['if'] = IF
NAME['else'] = ELSE
NAME['while'] = WHILE
NAME['say'] = SAY
ignore_comment = r'\#.*'
# Line number tracking
@_(r'\n+')
def ignore_newline(self, t):
self.lineno += t.value.count('\n')
def error(self, t):
print("t: ", t)
print('Line %d: Bad character %r' % (self.lineno, t.value[0]))
self.index += 1
Parser class解析器 class
class NoobpyParser(Parser):
# Get the token list from the lexer (required)
tokens = NoobpyLexer.tokens
log = logging.getLogger()
log.setLevel(logging.ERROR)
# debugfile = 'parser.out'
precedence = (
('left', PLUS, MINUS),
('left', TIMES, DIVIDE),
('right', UMINUS)
)
def __init__(self):
self.variables = {}
@_('')
def statement(self, p):
pass
@_('SAY expr')
def statement(self, p):
return 'say', p.expr
@_('NAME')
def expr(self, p):
return 'var', p.NAME
@_('var_assign')
def statement(self, p):
return p.var_assign
@_('NAME ASSIGN expr')
def var_assign(self, p):
return 'var_assign', p.NAME, p.expr
@_('expr')
def statement(self, p):
return p.expr
@_('expr PLUS expr')
def expr(self, p):
return 'add', p.expr0, p.expr1
@_('expr MINUS expr')
def expr(self, p):
return 'sub', p.expr0, p.expr1
@_('expr TIMES expr')
def expr(self, p):
return 'mul', p.expr0, p.expr1
@_('expr DIVIDE expr')
def expr(self, p):
return 'div', p.expr0, p.expr1
@_('MINUS expr %prec UMINUS')
def expr(self, p):
expression = list(p.expr)
if isinstance(expression[1], tuple):
res = 0
for i in expression[1]:
res += i
expression[1] = res
expression[1] = -expression[1]
return expression
@_('expr EQ expr')
def expr(self, p):
return 'eq', p.expr0, p.expr1
@_('"(" expr ")"')
def expr(self, p):
return p.expr
@_('NUMBER')
def expr(self, p):
return 'num', p.NUMBER
@_('STRING')
def expr(self, p):
return 'str', p.STRING
@_('TRUE')
def expr(self, p):
return p.TRUE
@_('FALSE')
def expr(self, p):
return p.FALSE
Execute class执行 class
class NoobpyExecute:
def __init__(self, tree, variables):
self.variables = variables
result = self.walkTree(tree)
if result is None:
pass
elif result is not None and type(result) in [int, float]:
print(result)
elif isinstance(result, str):
print(result)
elif isinstance(result, bool):
if result is True:
print("true")
else:
print("false")
def walkTree(self, node):
if isinstance(node, int):
return node
if isinstance(node, str):
return node
if node is None:
return None
if node[0] == 'say':
return self.walkTree(node[1])
if node[0] == 'num':
return node[1]
if node[0] == 'str':
return node[1]
if node[0] == 'eq':
return self.walkTree(node[1]) == self.walkTree(node[2])
if node[0] == 'add':
return self.walkTree(node[1]) + self.walkTree(node[2])
elif node[0] == 'sub':
return self.walkTree(node[1]) - self.walkTree(node[2])
elif node[0] == 'mul':
return self.walkTree(node[1]) * self.walkTree(node[2])
elif node[0] == 'div':
return self.walkTree(node[1]) / self.walkTree(node[2])
if node[0] == 'var_assign':
self.variables[node[1]] = self.walkTree(node[2])
if node[0] == 'var':
try:
return self.variables[node[1]]
except LookupError:
print("Undefined name '{}'".format(node[1]))
return 0
This:这个:
if __name__ == '__main__':
lexer = NoobpyLexer()
parser = NoobpyParser()
variables = {}
args = argparse.ArgumentParser()
args.add_argument(metavar='filename', dest="filename", type=str, help='name of the file you want to run')
args = args.parse_args()
with open(args.filename) as file:
for line in file.readlines():
tree = parser.parse(lexer.tokenize(line))
NoobpyExecute(tree, variables)
Example test.noob示例 test.noob
x = 2
x
^ prints 2 ^ 打印 2
In your NoobPy
constructor, you print out the result of evaluating the syntax tree (unless it's None, which will happen if you evaluate an assignment):在你的
NoobPy
构造函数中,你打印出评估语法树的结果(除非它是 None,如果你评估一个赋值,就会发生这种情况):
if result is None:
pass
elif result is not None and type(result) in [int, float]:
print(result)
elif isinstance(result, str):
print(result)
elif isinstance(result, bool):
if result is True:
print("true")
else:
print("false")
Leaving aside the fact that all that could be simplified, the code seems to clearly indicate that the intention of printing the result of the evaluation.撇开所有可以简化的事实不谈,代码似乎清楚地表明了打印评估结果的意图。 If you now don't want to print the result of the evaluation, you shouldn't print the result of the evaluation.
如果您现在不想打印评估结果,则不应打印评估结果。
When you see a say
function in the tree, you return the result of evaluating its argument:当您在树中看到
say
时,您返回评估其参数的结果:
if node[0] == 'say':
return self.walkTree(node[1])
If you want the say
function to have the effect of printing the result of the evaluation of its argument, you should print the result of the evaluation of its argument instead of returning the result of the evaluation of its argument (or as well as returning the result, depending on what you think the semantics of say
are).如果您希望
say
function 具有打印其参数的评估结果的效果,您应该打印其参数的评估结果而不是返回其参数的评估结果(或返回结果,取决于您认为say
的语义是什么)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.