在yacc规则中注入新的词法

时间:2016-01-04 16:54:28

标签: python grammar yacc lex ply

我有以下语法(这是一个简化的语法):

S -> EXPR

EXPR -> ITEM addop EXPR
EXPR -> ITEM

ITEM -> num
ITEM -> ident

具有:

num: a floating point number
ident: a string representing an identifier
addop: +

我正在使用PLY库进行python,并且具有以下代码:

def p_L_S(self,p):
  ''' S : EXPR'''
  p[0] = p[1]

def p_L_EXPR_1(self,p):
  ''' EXPR : ITEM addop EXPR'''
  p[0] = p[1] + p[2]

def p_L_EXPR_2(self,p):
  ''' EXPR : ITEM'''
  p[0] = p[1]

def p_L_ITEM_1(self,p):
  ''' ITEM : num '''
  p[0] = float(p[1])

def p_L_ITEM_2(self,p):
  ''' ITEM : ident '''
  p[0] = value_of_expr_associated_to_ident(p[1])

[...]

在最后一个函数(p_L_ITEM_2)中我想解释与p [1]相关联的字符串(这是语法识别的表达式),而不启动另一个解析。 今天,函数value_of_expr_associated_to_ident启动与parse关联的表达式的新解析(调用ident方法)。 但即使有效,这也会带来非常糟糕的表现。

有没有办法向解析器发送与ident相关的表达式相关联的词汇,以避免开始新的解析?

我不知道这是否清楚,如果不是,我会尽力澄清。

非常感谢。 萨姆

1 个答案:

答案 0 :(得分:1)

如果您尝试使用函数式语言进行某种惰性求值,请继续阅读。这并不像它看起来那么容易,而且我还没有提供任何关于这种方法的粗略想法。

如果与标识符关联的值是表示语言中表达式的纯字符串,则需要执行递归调用解析。

但似乎至少可以缓存生成的解析树(这意味着你的解析器需要创建一个解析树,而不是立即进行评估)。或者,您可以在将字符串值分配给变量时将其解析为解析树。

但是,您完成了递归解析,您需要以某种方式处理无限递归,例如r r(或r + 1)的值。