Проблемы с PLY Lex и Yacc

59
9

У меня возникли проблемы с использованием PLY. Я читал документацию и решил попробовать примеры. Пример lexing работал отлично, но разбор я не мог работать. Я также, глядя на документы, не понимаю, как вы взаимодействуете с lex и yacc вместе, чтобы создать правильный компилятор. Парсер включал только лексеры, доступные для токенов, и насколько я больше ничего не могу сказать.

Я добавил несколько вещей, таких как цвет (модуль Colorama) и несколько разные сообщения, но, кроме того, это похоже на пример:

#!/usr/bin/env python

### LEXICAL ANALYSIS ###

import ply.lex as lex

import colorama
colorama.init()

tokens = (
"NUMBER",
"PLUS",
"MINUS",
"MULTIPLY",
"DIVIDE",
"LBRACKET",
"RBRACKET"
)

t_PLUS = r"\+"
t_MINUS = r"-"
t_MULTIPLY = r"\*"
t_DIVIDE = r"/"
t_LBRACKET = r"\("
t_RBRACKET = r"\)"

t_ignore = "\t\r "

def t_NUMBER(t):
r"\d+"
t.value = int(t.value)
return t

def t_newline(t):
r"\n+"
t.lexer.lineno += len(t.value)

def t_COMMENT(t):
r"\#.*"
print "Comment:", t.value

def t_error(t):
print colorama.Fore.RED + "\n\nLEXICAL ERROR: line", t.lexer.lineno, "and position", t.lexer.lexpos, "invalid token:", t.value.split("\n")[0] + colorama.Fore.RESET
t.lexer.skip(len(t.value))

def mylex(inp):
lexer = lex.lex()

lexer.input(inp)

for token in lexer:
print "Token:", token

Это работает отлично, но парсер, однако, не делает:

#!/usr/bin/env python

import ply.yacc as yacc

from langlex import tokens

def p_expression_plus(p):
"expression : expression PLUS term"
p[0] = p[1] + p[3]

def p_expression_minus(p):
"expression : expression MINUS term"
p[0] = p[1] - p[3]

def p_expression_term(p):
"expression : term"
p[0] = p[1]

def p_term_times(p):
"term : term MULTIPLY factor"
p[0] = p[1] * p[3]

def p_term_div(p):
"term : term DIVIDE factor"
p[0] = p[1] / p[3]

def p_term_factor(p):
"term : factor"
p[0] = p[1]

def p_factor_num(p):
"factor : NUMBER"
p[0] = p[1]

def p_factor_expr(p):
"factor : LBRACKET expression RBRACKET"
p[0] = p[2]

def p_error(p):
print "Syntax error!"

parser = yacc.yacc()

while True:
s = raw_input("calc > ")
if not(s):
continue
result = parser.parse(s)
print result

Я получаю следующую ошибку при попытке запустить ее:

calc > 5 + 10
Traceback (most recent call last):
File "C:\Users\Max\Desktop\lang\langyacc.py", line 49, in <module>
result = parser.parse(s)
File "C:\Python27\lib\site-packages\ply\yacc.py", line 265, in parse
return self.parseopt_notrack(input,lexer,debug,tracking,tokenfunc)
File "C:\Python27\lib\site-packages\ply\yacc.py", line 881, in parseopt_notrack
lexer = lex.lexer
AttributeError: 'module' object has no attribute 'lexer'

Я новичок в разработке lex, yacc и компилятора в целом и не знаю, почему это происходит. Любая помощь будет оценена по достоинству.

спросил(а) 2014-09-07T19:20:00+04:00 6 лет, 1 месяц назад
1
Решение
71

Вы не создали lexer в своем файле lexer. У вас это есть в функции mylex() но на самом деле она не построена.

Вытащите его из функции.

lexer = lex.lex()

def mylex(inp):
lexer.input(inp)
# etc.

ответил(а) 2014-09-07T20:00:00+04:00 6 лет, 1 месяц назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема