如何解决在 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 举报,一经查实,本站将立刻删除。