词法分析器,解析器,试图制作表达式计算器

时间:2017-11-14 22:59:32

标签: python-3.x parsing calculator ply

正如标题所说我试图使用Ply制作表达式计算器,我仍然没有完成整个代码只是其中的一部分,但直到现在。我收到此错误: Traceback(最近一次调用最后一次):   文件" EX3.py",第69行,in     parser = yacc.yacc()   文件" /Users/mostafa.osama2/anaconda3/lib/python3.6/site-packages/ply/yacc.py" ;,第3317行,在yacc中     引发YaccError('无法构建解析器') ply.yacc.YaccError:无法构建解析器

这是我的代码:

import ply.lex as lex
import ply.yacc as yacc
import sys

tokens = ['INT','FLOAT' , 'NAME' , 'PLUS' , 'MINUS' , 'DIVIDE' , 'MULTIPLY' ,
'EQUALS']

#list of tokens , for grammar checking

t_PLUS = r'\+'
t_MINUS = r'\-'
t_MULTIPLY = r'\*'
t_DIVIDE = r'\/'
t_EQUALS = r'\='

t_ignore = r' ' # used for ignoring spaces between numbers and operators

#has to match name of token, 

def t_FLOAT(t):
    r'\d+.\d+' # 1.2 is a float , 1.any number is a float
    t.value = float(t.value)
    return t

def t_INT(t):
    r'\d+'
    t.value = int(t.value)
    return t # t is our token object


def t_NAME(t):
    r'[a-zA-Z_][a-zA-Z_0-9]*' #star means 0 or more, first char is a-zA-z , second character is a-zA-z0-9
    t.type = 'NAME'
    return t

def t_error(t):
    print("Illegal characters!")
    t.lexer.skip(1) # skips 1 token onwards

lexer = lex.lex()

def p_calc(p): # p is  a  tuple
    '''
    calc : expression
        | empty
    '''
    print(p[1])

def p_expression(p):
    '''
    expression : expression PLUS expression
                | expression DIVIDE expression
                | expression PLUS expression
                | expression MINUS expression
    '''
    p[0] = (p[2] , p[1] , p[3])
def p_expression(p):
    '''
    expression : INT
                | FLOAT
    '''
    p[0] = p[1]
def p_empty(p):
    '''
    empty:
    '''
    p[0] = None

parser = yacc.yacc()
while True:
    try:
        s = input('')
    except EOFError: # when u press contorl D on keyboard
        break
        parser.parse(s)

1 个答案:

答案 0 :(得分:0)

Ply坚持认为解析规则在非终端名称和冒号之间有空格。所以empty:无效;你必须写empty :

另外,正如Ply所报告的那样,您定义了两个名为p_expression的函数。 Ply要求所有解析函数都有不同的名称(否则它无法调用它们),但它并不关心名称是什么,只要它们以p_开头即可。所以改变其中一个名字。

最后,你有两个加法规则,没有乘法规则。 Ply会抱怨重复添加规则(在您修复其他问题之后)。它还会抱怨您错过了p_error功能。