【问题标题】:PLY resolving ambiguity for simple sentence parserPLY 解决简单句子解析器的歧义
【发布时间】:2018-04-19 22:52:13
【问题描述】:

我遇到了一个问题,我需要将非常简单的句子解析为 BNF 解析。我能够轻松地标记标记并使用简单的句子。但是,有几种情况可以应用 reduce 规则,或者发生转变,并且可能发生另一个 reduce。例如:

杰瑞德追着汤姆和杰瑞吃饭。

我有一条规则将名词连词减少为名词短语,还有另一条规则将句子连词减少为复合句。在“Jerry”,它似乎自动假定句子是名词动词名词短语的形式,而不是句子连词,并且在遇到“ate”时抛出错误,因为 NP VP NP VP 没有重写规则.

我怎样才能改变这个,如果连词右边的词是一个句子,它就会把它解析为 S CONJ S,但如果不是,那么它就会被解析为 NP VP NP?

编辑:为澄清起见,这是我当前的代码:

import ply.yacc as yacc
from lexer import tokens

precedence = (('left', 'Vi'),('left', 'N'))

def p_S(p):
    """S : NP VP"""
    p[0] = '[S ' + p[1] + ' ' + p[2] + ' ]'

def p_VP(p):
    """VP : VP Conj VP"""
    p[0] = '[VP ' + p[1] + ' ' + p[2] + ' ' + p[3] + ' ]'

def p_Vi(p):
    """VP : Vi"""
    p[0] = '[VP [VI ' + p[1] + ' ] ]'

def p_Vt(p):
    """VP : Vt NP"""
    p[0] = '[VP [Vt ' + p[1] + ' ] ' + p[2] + ' ]'

def p_Vd(p):
    """VP : Vd NP NP"""
    p[0] = '[VP [VT ' + p[1] + ' ] ' + p[2] + ' ' + p[3] + ' ]'

def p_NP(p):
    """NP : NP Conj NP
    | N"""
    if len(p) == 4:
        p[0] = '[NP ' + p[1] + ' [Conj ' + p[2] + ' ] ' + p[3] + ' ]'
    else:
        p[0] = '[N ' + p[1] + ' ]'

def p_error(p):
    print("Syntax Error in input!\n")

parser = yacc.yacc()
while True:

    try:
        s = input('calc > ')
        if not s: continue
        result = parser.parse(s)
        if result is not None: print(result + '\n')
    except EOFError:
        print("Please try again")

【问题讨论】:

    标签: python parsing ply


    【解决方案1】:

    你不能,至少不能使用 Ply 构建的确定性单令牌前瞻解析器。

    幸运的是(或不是)人脑并不局限于 Knuthian 从左到右的解析,尽管我们如何解析句子的细节并不完全清楚。更重要的是,大多数人类语言实际上是模棱两可的,只有语义分析才能区分多种可能的解析。 (在口语中,还有一些其他的语言特征,如语调、字间距和强调,也有助于指导解析。这些特征通常不会转录成书面语言,但可以处理书面语言非线性;如有必要,眼睛可以重新阅读或向前扫描。)

    对于人类语言解析,GLR 或类似算法将被证明更有用。尽管 Bison 可以生成 GLR 解析器,但据我所知,该功能尚未在 Ply 中实现。图表解析不是特别复杂;您可能无需太多工作就可以编写自己的代码。但是,除非您对解析算法感兴趣,否则没有多大意义,因为 Python 中已有用于人类语言处理的包。

    (SO 不鼓励推荐库,但我相信自然语言工具包 NLTK 可能是用于人类语言处理的最广泛使用的 Python 框架。)

    【讨论】:

    • 感谢您的详细解释,这一切都很有意义!我最终只是修改了我的 Lexer,所以它使用相当准确的启发式(不是​​ 100%,但对于基本情况来说足够好)区分名词连词、动词连词和句子连词
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-04
    • 1970-01-01
    • 2011-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多