无限递归 - 预测解析器

时间:2014-06-19 21:01:24

标签: python parsing grammar

好吧,我有一个问题来处理这个语法:

R -> a R | e

e =空产。

当我尝试派生这些输入时: "a""aa""aaa" ..我进行了无限递归。

def match(t):
    global pos
    global lookahead
    if lookahead == t:
        try:
            pos += 1
            lookahead = inputstr[pos]
        except IndexError:
            pass
    else:
        raise SyntaxError("syntax error!")

def r():
    if lookahead == 'a':
        match('a') 
        r()
    else:
        pass # e-production

inputstr = raw_input()
lookahead = inputstr[0]
pos = 0
r()

我知道,前瞻不变,但我该如何解决?我是语法和解析器的初学者。

1 个答案:

答案 0 :(得分:0)

IndexError内的传递错误。一旦输入用完, 并且每个匹配操作都是正确的,程序应终止并具有确定状态。 但是,在原始代码中,不会终止, 但保持读取超出输入缓冲区并捕获自己的IndexErrors。 这会导致无限递归。 在预测解析器中捕获了三个错误:

  • 不正确的匹配。
  • 在没有epsilon规则的情况下从变量中删除switch-case语句。
  • 当输入未被读取直到结束时从s()返回。

为了解决这个问题,我添加了最后一个if语句。 总而言之,正确的预测解析器是这样的:

#!/usr/bin/python

import sys

def finish(msg):
    print msg
    sys.exit()

def eat(t):
    global pos
    global lookahead
    if lookahead == t:
        try:
            pos += 1
            lookahead = inputstr[pos]
        except IndexError:
            #pass is wrong here ...
            finish("OK")
    else:
        finish("ERROR")


def r():
    if lookahead == 'a':
        eat('a') 
        r()
    else:
        pass # e-production

inputstr = raw_input()
lookahead = inputstr[0]
pos = 0
r()
##########################
# This needs to be added #
##########################
if pos != len(inputstr):
    finish("ERROR")