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.


Reply via email to