简体   繁体   English

如何使用PHP preg_match_all实现简单的CFG解析器?

[英]How can I implement simple CFG parser using PHP preg_match_all?

I am using preg_match_all to make a simple parser. 我正在使用preg_match_all进行简单的解析器。 Note that since it will parse only few sentences, the performance does not matter. 请注意,由于它将仅解析少量句子,因此性能无关紧要。 Would it be possible to make a parser which parse through below Context free grammer? 是否有可能使解析器通过以下上下文无关语法进行解析?

S -> NP VP
PP -> P NP
NP -> 'the' N | N PP | 'the' N PP
VP -> V NP | V PP | V NP PP
N -> 'cat'
N -> 'dog'
N -> 'rug'
V -> 'chased'
V -> 'sat'
P -> 'in'
P -> 'on'

The problem here that I couldn't resolve was loop. 我无法解决的问题是循环。

For example, do you see loop where there can be PP -> NP -> PP and so on? 例如,您是否看到可以在其中出现PP-> NP-> PP等的循环?

Is there anything in PHP that works like Push-down automata that can solve this problem? PHP中有什么可以像下推式自动机一样解决此问题?

Example input: 'the cat chased the dog' 输入示例:“猫追了狗”

Example output: 输出示例:

(S (NP the (N cat)) (VP (V chased) (NP the (N dog)))) (S(NP(N只猫))(VP(V追逐)(NP(N只狗))))

Example input: 'the cat chased the dog on the rug' 输入示例:“猫在地毯上追赶狗”

Example output(s): 示例输出:

(S (NP the (N cat)) (VP (V chased) (NP the (N dog) (PP (P on) (NP the (N rug)))))) (S(NP(N cat))(VP(V追逐)(NP(N dog)(PP(P on)(NP the(N rug)))))))

(S (NP the (N cat)) (VP (V chased) (NP the (N dog)) (PP (P on) (NP the (N rug))))) (S(NP(N cat))(VP(V追逐)(NP(N dog))(PP(P on)(NP the(N rug)))))

The usual approach here is to write a predictive parser. 这里通常的方法是编写一个预测解析器。 For you, this could mean using regular expressions to match either a noun, verb or predicate and then deciding what production to use. 对您来说,这可能意味着使用正则表达式匹配名词,动词或谓词,然后确定要使用的生产形式。 You are correct that parsing a grammar requires the computational power of a push-down automata (ie more than what a regular expression alone can achieve). 您是正确的,语法解析需要下推自动机的计算能力(即比仅使用正则表达式所能实现的功能还要多)。 Simulating a push-down automaton is one approach and is what parser generators like yacc/bison often do. 模拟下推自动机是一种方法,并且是解析器生成器(如yacc / bison)经常执行的操作。 For a small grammar like that though, you can use the call stack implicitly. 但是对于这样的小语法,您可以隐式使用调用堆栈。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM