PLY词法分析和语法分析问题

1 投票
1 回答
7244 浏览
提问于 2025-04-20 07:27

我在使用PLY的时候遇到了一些麻烦。我看了看文档,决定试试里面的例子。词法分析的例子运行得很好,但语法分析我却搞不定。我还发现,文档里我不太明白怎么把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和编译器开发都是新手,完全不知道为什么会这样。任何帮助都非常感谢。

1 个回答

4

你在你的词法分析器文件里还没有构建词法分析器。虽然你在 mylex() 这个函数里写了它,但实际上并没有真正构建出来。

把它从这个函数里拿出来。

lexer = lex.lex()

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

撰写回答