Hello,
I decided to use ply to implement assembler from "Elements of computer
systems" and in the process I noticed an unexpected behaviour (error
on someone's part) on something that in my opinion looks ok.
Here's the program showing the error:
import ply.lex as lex
import ply.yacc as yacc
#####################
# LEXER
#####################
tokens = [
'SEMICOLON',
'EQUAL',
'JUMP',
'REGISTER',
]
t_ignore = ' \r'
t_SEMICOLON = r';'
t_EQUAL = r'='
def t_ID(t):
r'(?:D|JMP)'
if t.value == 'D':
t.type = 'REGISTER'
t.value = ('REGISTER', t.value)
elif t.value == 'JMP':
t.type = 'JUMP'
return t
def t_error(t):
print "Illegal character '%s'" % t.value[0]
t.lexer.skip(1)
#####################
# PARSER
#####################
def p_c_order(p):
'c_order : dest op jmp'
pass
def p_dest(p):
'dest : REGISTER EQUAL'
pass
def p_dest_empty(p):
'dest : empty'
pass
def p_op(p):
'op : REGISTER'
pass
def p_jmp(p):
'jmp : SEMICOLON JUMP'
pass
def p_empty(p):
'empty :'
pass
def p_error(p):
print "Syntax error in input! " + str(p)
lexer = lex.lex()
parser = yacc.yacc()
if __name__ == '__main__':
parser.parse('D;JMP')
It is a minimal example I could made of a lexer and parser of simple
assembly language.
It is supposed to parse orders like: D=A+D;JMP (register D is equal to
sum of A and D, JMP to the address pointed by A) or D;JEQ (Jump to the
address pointed by D if D == 0).
I stripped out everything I could. I only left the ability to
recognize register D, equal sign, semicolon and JMP instruction. So it
can parse ("D=D;JMP"), but on ("D;JMP") it returns an error
Here's the debug output:
PLY: PARSE DEBUG START
State : 0
Stack : . LexToken(REGISTER,('REGISTER', 'D'),1,0)
Action : Shift and goto state 3
State : 3
Stack : REGISTER . LexToken(SEMICOLON,';',1,1)
ERROR: Error : REGISTER . LexToken(SEMICOLON,';',1,1)
Syntax error in input! LexToken(SEMICOLON,';',1,1)
State : 3
Stack : REGISTER . error
ERROR: Error : REGISTER . error
State : 0
Stack : . error
ERROR: Error : . error
State : 0
Stack : . LexToken(JUMP,'JMP',1,2)
ERROR: Error : . LexToken(JUMP,'JMP',1,2)
State : 0
Stack : . $end
ERROR: Error : . $end
What's interesting if I add following rule:
def p_c_order_empty(p):
'c_order : op jmp'
pass
It works! However if I add this rule:
def p_c_order_empty(p):
'c_order : empty op jmp'
pass
Or change p_dest_empty(p) to:
def p_dest_empty(p):
'dest : '
pass
The error remains the same. Even though it seems (to me) to be the
same.
Can someone explain what's happening here? Is it an error on my part
or perhaps it seems to be a bug?
--
You received this message because you are subscribed to the Google Groups
"ply-hack" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit https://groups.google.com/groups/opt_out.