私は次のような方程式の方程式パーサーを作成しようとしています。トークンを取得するため、およびパーサーモジュールとして4*sin(1+cos(10/2))
使用します。lex
yacc
私の実際の問題は、関数の文法を定義する方法がわからないことです。関数は通常このFunctionName( Expression)
ように構築されるため、パーサー文法の場合は次のようになりますfunction : FUNCTION LPAREN expression RPAREN
(私は願っています)。
しかし、そのように構築された関数をどのように扱うのでしょうかsin(3+cos(0)*10)
。3+
これは、関数内の関数であり、とを気にすることを忘れないで*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)
前もって感謝します!ジョン