微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 pythonnand2tetris 项目

如何解决在 pythonnand2tetris 项目

如下代码,词法分析器没有问题,我构建解析器也没有问题。但是,当我想解析一些简单的文本时,解析器似乎首先调用错误消息。如下面的代码和调试信息,在while进入堆栈后,解析器只调用p_error。我想问题是在处理移位规则 p[0]=p[1] 时出现了一些错误,我尝试阅读 David M. Beazley 编写的指令,但并没有真正理解。我仍然不清楚 p[0]=p[1] 如何与 shift 和 reduce 规则相关联。 (经过一些修复,我确定了主要问题。问题已编辑)

所以问题是: 1.如何才能让我的程序正确解析?

2.p[0]=p[1] 是什么意思?这意味着转移还是减少?而且,我看到一些程序写了p[0]=p[1]/p[2],我不明白为什么/可以这样写。我认为它类似于 '/' 或被视为令牌并跳过它。

谢谢!!

import ply.lex as lex
import ply.yacc as yacc
class JackLexer:
       ......

        ##########expression#################

    def p_error(self,p):
        print('Syntax error,p: ',p,'\n\n')
        if not p: return
    start='start'
    #delete expression,since there won't be a sentence only with expression
    def p_start(self,p):
        '''
        start : CLASS className '{' classVarDec subroutineDec '}'
              | statement
        '''
        print('start,p=:  ',p)
        if len(p)==2:
            p[0]=p[1]
        else:
            p[0]=[p[2],p[4],p[5]]
        print('p[0]is Now after executing p[0]=p[1] in p_start:  ',p[0])
    def p_expression(self,p):
        '''
        expression : term 
                   | term opterm 
    
        '''
        print('expression,p=:',p)
        if len(p)==2:
            p[0]=p[1]
        else:
            p[0]=[p[1]]+p[2]
        
    #= (op term)*
    def p_opterm(self,p):
        '''
        opterm : op term
               | opterm opterm
               | empty
        
        ''' 
        if len(p)==3:
            p[0]=[p[1],p[2]]
        else:
            pass
        
    def p_term(self,p):
        '''
        term : integerConstant
             | StringConstant
             | keyword
             | varName
             | varName '[' expression ']'
             | subroutineCall
             | '(' expression ')'
             | unaryOp term
        
        '''
        if len(p)==2:
            p[0]=p[1]
        elif len(p)==3:
            p[0]=[p[1]]+p[2]
        elif len(p)==5:
            p[0]=[p[1]]+p[3]
        elif len(p)==4:
            p[0]=p[2]  
    
    def p_subroutineCall(self,p):
        '''
        subroutineCall : subroutineName '(' expressionList ')'
                       | classvarName '.' subroutineName '(' expressionList ')'
        
        '''
        if len(p)==5:
            p[0]=[p[1]]+p[3]
        else:
            p[0]=[p[1]]+p[3]+p[5]
    def p_classvarName(self,p):
        '''
        classvarName : className
                     | varName
        
        '''
            
        p[0]=p[1]
            
    def p_expressionList(self,p):
        '''
        expressionList : empty
                       | expression expression_comma
        '''
        if len(p)==3:
            p[0]=[p[1]]+p[2]
        else:
            pass
        
    def p_expression_comma(self,p):
        '''
        expression_comma : ',' expression
                         | expression_comma expression_comma
                         | empty
        '''
        if p[1]==',':
            p[0]=p[2]
        elif len(p)==3:
            p[0]=[p[1]]+p[2]
        else:
            pass
        
        
        
    def p_op(self,p):
        '''
        op : symbol
        '''
        p[0]=p[1]
    
    def p_unaryOp(self,p):
        '''
        unaryOp : '-' 
                | '~'
        '''
        p[0]=p[1]
    

    def p_empty(self,p):#??
        'empty :'
        pass
    
#######################################statement##############################
        
    def p_statement(self,p):
        '''
        statement : empty
                  | statement letStatement
                  | statement ifStatement
                  | statement whileStatement
                  | statement doStatement
                  | statement ReturnStatement
                  | letStatement
                  | ifStatement
                  | whileStatement
                  | doStatement
                  | ReturnStatement
        '''
        print('this is statement:',p)
        if p[1]=='':
            pass
        elif len(p)==3:
            p[0]=[p[1]]+p[2]
        else:
            p[0]=p[1]
    
    def p_letStatement(self,p):
        '''
        letStatement : LET varName letdesuka '=' expression ';'
        '''
        p[0]=[p[2]]+p[3]+p[5]
    def p_letdesuka(self,p):
        '''
        letdesuka : empty
                  | '[' expression ']'
        '''
        if len(p)==4:
            p[0]=p[2]
        else:
            pass
        
    def p_ifStatement(self,p):
        '''
        ifStatement : IF '(' expression ')' '{' statement '}' elsedesuka
        
        '''
        p[0]=[p[3]]+p[6]+p[8]
        
        
    def p_elsedesuka(self,p):
        '''
        elsedesuka : empty
                   | ELSE '{' statement '}'
        '''
        if len(p)==5:
            p[0]=p[3]
        else:
            pass
        
        
    def p_whileStatement(self,p):
        '''
        whileStatement : WHILE '(' expression ')' '{' statement '}'
        '''
        print('this is whileStatement,p)
        p[0]=['while']+'('+p[3]+')'+'{'+p[6]+'}'
        print(p[0])
        
    def p_doStatement(self,p):
        '''
        doStatement : DO subroutineCall ';'
        '''
        p[0]=p[2]
    def p_ReturnStatement(self,p):
        '''
        ReturnStatement : RETURN expressiondesuka
        '''
        p[0]=p[2]
    def p_expressiondesuka(self,p):
        '''
        expressiondesuka : empty
                         | expression
        '''
        if len(p)==2:
            p[0]=p[1]
        else:
            pass

    


    def buildParser(self):
        reserved = {'class':'CLASS','constructor':'CONSTRUCTOR','function':'FUNCTION','method':'METHOD','field':'FIELD','static':'STATIC','var':'VAR','int':'INT','char':'CHAR','boolean':'BOOLEAN','void':'VOID','true':'TRUE','false':'FALSE','null':'NULL','this':'THIS','let':'LET','do':'DO','if' : 'IF','else' : 'ELSE','while' : 'WHILE','return':'RETURN'}
        tokens=['keyword','symbol','integerConstant','StringConstant','identifier']+ list(reserved.values())#list
        #start='statement'
        self.parser=yacc.yacc(module=self)
    
        
    def parse(self,data):
        s=self.parser.parse(data,debug=1)
        
        

此外,在尝试解析while(x=2){x+3;}\nlet x=5时,我在下面收到了调试消息,但我希望将 keyword 移动并减少为 term

PLY: PARSE DEBUG START

State  : 0
Stack  : . LexToken(keyword,'while',2,0)
ERROR: Error  : . LexToken(keyword,0)

State  : 0
Stack  : . LexToken(symbol,'(',5)
ERROR: Error  : . LexToken(symbol,5)

State  : 0
Stack  : . LexToken(identifier,'x',6)
ERROR: Error  : . LexToken(identifier,6)

State  : 0
Stack  : . LexToken(symbol,'=',7)
ERROR: Error  : . LexToken(symbol,7)

State  : 0
Stack  : . LexToken(integerConstant,8)
ERROR: Error  : . LexToken(integerConstant,8)

State  : 0
Stack  : . LexToken(symbol,'){',9)
ERROR: Error  : . LexToken(symbol,9)

State  : 0
Stack  : . LexToken(identifier,11)
ERROR: Error  : . LexToken(identifier,11)

State  : 0
Stack  : . LexToken(symbol,'+',12)
ERROR: Error  : . LexToken(symbol,12)

State  : 0
Stack  : . LexToken(integerConstant,3,13)
ERROR: Error  : . LexToken(integerConstant,13)

State  : 0
Stack  : . LexToken(symbol,';}',14)
ERROR: Error  : . LexToken(symbol,14)

State  : 0
Stack  : . LexToken(keyword,'let',17)
ERROR: Error  : . LexToken(keyword,17)

State  : 0
Stack  : . LexToken(identifier,21)
ERROR: Error  : . LexToken(identifier,21)

State  : 0
Stack  : . LexToken(symbol,22)
ERROR: Error  : . LexToken(symbol,22)

State  : 0
Stack  : . LexToken(integerConstant,5,23)
ERROR: Error  : . LexToken(integerConstant,23)

State  : 0
Stack  : . $end
Action : Reduce rule [empty -> <empty>] with [] and goto state 4
Result : <nonetype @ 0x7ffa8b2ba880> (None)

State  : 4
Stack  : empty . $end
Action : Reduce rule [statement -> empty] with [None] and goto state 3
Result : <nonetype @ 0x7ffa8b2ba880> (None)

State  : 3
Stack  : statement . $end
Action : Reduce rule [start -> statement] with [None] and goto state 1
Result : <nonetype @ 0x7ffa8b2ba880> (None)

State  : 1
Stack  : start . $end
Done   : Returning <nonetype @ 0x7ffa8b2ba880> (None)
PLY: PARSE DEBUG END

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。