我正在尝试为以下等式编写一个等式解析器:4*sin(1+cos(10/2))
我lex
用来获取令牌并yacc
作为解析器模块。
我现在的实际问题是我不知道如何定义函数的语法。一个函数通常是这样构造的,FunctionName( Expression)
所以对于解析器语法来说function : FUNCTION LPAREN expression RPAREN
(我希望)。
但是我将如何处理这样构建的功能sin(3+cos(0)*10)
。这将是一个函数中的一个函数,不要忘记关心3+
and *10
。希望我已经指出我的问题足够好。
这是我的代码:
import ply.lex as lex
import ply.yacc as yacc
import math
tokens = (
'DIV',
'TIMES',
'MINUS',
'PLUS',
'FUNCTION',
'NUMBER',
'LPAREN',
'RPAREN',
)
t_PLUS = r'\+'
t_MINUS = r'-'
t_TIMES = r'\*'
t_DIV = r'/'
t_LPAREN = r'\('
t_RPAREN = r'\)'
t_ignore = ' '
def t_NUMBER(t):
r'([0-9]*\.[0-9]+|[0-9]+)'
t.value = float(t.value)
return t
def t_FUNCTION(t):
r'sin|cos|tan'
return t
def t_error(t):
print("Illegal character '%s'" % t.value[0])
t.lexer.skip(1)
# Parser
'''
Here i need some help
'''
def p_function_exp(p):
'function : expression PLUS function'
p[0] = p[1] + p[3]
def p_function(p):
'function : FUNCTION LPAREN expression RPAREN'
if p[1] == 'sin':
p[0] = math.sin(p[3])
def p_expression_minus(p):
'expression : expression MINUS term'
p[0] = p[1] - p[3]
def p_expression_plus(p):
'expression : expression PLUS term'
p[0] = p[1] + p[3]
def p_expression_term(p):
'expression : term'
p[0] = p[1]
def p_term_div(p):
'term : term DIV factor'
p[0] = p[1] / p[3]
def p_term_times(p):
'term : term TIMES factor'
p[0] = p[1] * p[3]
def p_term_factor(p):
'term : factor'
p[0] = p[1]
def p_factor(p):
'factor : NUMBER'
p[0] = p[1]
def p_factor_exp(p):
'factor : LPAREN expression RPAREN'
p[0] = p[2]
# Error rule for syntax errors
def p_error(p):
print("Syntax error in input!")
# Build the parser
parser = yacc.yacc()
while True:
try:
s = input('>> ')
equation = lex.lex()
equation.input(s)
while True:
tok = equation.token()
if not tok: break
print(tok)
except EOFError:
break
if not s: continue
result = parser.parse(s)
print(result)
提前致谢!约翰