【问题标题】:Infinite recursion - predictive parser无限递归 - 预测解析器
【发布时间】:2014-06-19 21:01:23
【问题描述】:

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

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()

我知道,前瞻没有改变,但我该如何解决这个问题?我是语法和解析器的初学者。

【问题讨论】:

  • 简而言之,尽管输入用完后会出现IndexErrors,但您仍会不断增加pos。除修复此代码所需的其他事项外,我建议从删除所有全局变量开始。 (除了读取输入之外,完全没有可变状态的额外功劳。)
  • 现在它可以正常工作了。没有全局变量,我无法思考。
  • @dxhj 思考参数和return
  • @jonrsharpe 或某种StreamParser 对象...
  • 你能举个例子吗? (“简而言之,尽管输入用完后会出现 IndexErrors,但你会不断增加 pos。”)

标签: python parsing grammar


【解决方案1】:

IndexError 里面的pass 是错误的。一旦输入用尽, 并且每个匹配操作都是正确的,程序应该以 OK 状态终止。 但是,在您的原始代码中,它不会终止, 但不断读取输入缓冲区之外的内容并捕获它自己的 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")

【讨论】:

    猜你喜欢
    • 2013-01-13
    • 1970-01-01
    • 1970-01-01
    • 2018-03-25
    • 1970-01-01
    • 2012-03-26
    • 1970-01-01
    • 1970-01-01
    • 2019-02-21
    相关资源
    最近更新 更多