PLY:错过了“if”语句 注意事项

问题描述

这是我第一次尝试使用 PLY 或任何词法分析器/解析器工具,所以我不确定出了什么问题。

我正在尝试基于 Python 语法松散地实现一种小型汇编语言,尤其是对于带有缩进块的 if 语句。这是一个例子:

if d0 == 0x42:
    a1 = d2
d0 = 0

我编写了一个解析器来处理 INDENTDEDENT,从而生成此标记列表:

LexToken(IF,'if',1,0)
LexToken(REGISTER,'d0',3)
LexToken(IS_EQUAL,'==',6)
LexToken(NUMBER,'0x42',9)
LexToken(COLON,':',13)
LexToken(INDENT,'\t',2,15)
LexToken(REGISTER,'a1',16)
LexToken(EQUAL,'=',19)
LexToken(REGISTER,'d2',21)
LexToken(DEDENT,3,24)
LexToken(REGISTER,24)
LexToken(EQUAL,27)
LexToken(NUMBER,'0',29)

似乎没问题(INDENTDEDENT valuelinenolexpos 是错误的,但我不使用它们)

我的解析器是:

import ply.yacc as yacc

# Get the token map from the lexer.  This is required.
from asmlexer import tokens,MyLexer
from instr import *


def p_statement_assignment(p):
    'statement : assignment'
    print('statmt1 :',[x for x in p])
    p[0] = p[1]
    
def p_statement_ifstatmt(p):
    'statement : ifstatmt'
    print('statmt2 :',[x for x in p])
    p[0] = p[1]
    
def p_assignment(p):
    'assignment : value EQUAL value'
    print("assignment :",[x for x in p])
    p[0] = Move(p[3],p[1])

def p_ifstatmt(p):
    'ifstatmt : IF condition COLON INDENT statement DEDENT'
    print("IF :",[x for x in p])
    p[0] = If(p[2],body = p[5])

def p_condition_equal(p):
    'condition : value IS_EQUAL value'
    print("condition ==",[x for x in p])
    p[0] = "%s == %s" % (p[1],p[3])
    
def p_value_register(p):
    'value : REGISTER'
    print('register :',[x for x in p])
    p[0] = Register(p[1])

def p_value_number(p):
    'value : NUMBER'
    print('value:',[x for x in p])
    p[0] = Value(p[1])

# Error rule for syntax errors
def p_error(p):
    print(p)
    print("Syntax error in input!")

# Build the parser
class MyParser(object):
    def __init__(self):
        lexer = MyLexer()
        self.lexer = lexer
        self.parser = yacc.yacc()
    
    def parse(self,code):
        self.lexer.input(code)
        result = self.parser.parse(lexer = self.lexer)
        return result

if True:
    with open("test.psm") as f:
        data = f.read()

    parser = MyParser()
    result = parser.parse(data)
    print(result)
    print(result.get_code())

似乎缺少 IF 令牌:

register : [None,'d0']
value: [None,'0x42']
condition == [None,<instr.Register object at 0x000002429DA5E340>,<instr.Value object at 0x000002429DA5E250>]
register : [None,'a1']
register : [None,'d2']
assignment : [None,<instr.Register object at 0x000002429DA2C970>,<instr.Register object at 0x000002429DA5E5E0>]
statmt1 : [None,<instr.Move object at 0x000002429DA5E370>]
LexToken(REGISTER,24)
Syntax error in input!
value: [None,'0']
None
Traceback (most recent call last):
  File ".\asmparser.py",line 137,in <module>
    print(result.get_code())
AttributeError: 'NoneType' object has no attribute 'get_code'

我不明白为什么...

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)