考虑以下对无上下文语法的扩展,该语法允许规则在左侧,非终端右侧的一个(或多个)终端.也就是说,形式的规则:
A b -> ...
Run Code Online (Sandbox Code Playgroud)
右侧可以是任何东西,例如在无上下文的语法中.特别是,不要求右侧的末端具有完全相同的终端符号.在这种情况下,此扩展将是上下文相关的.但终端不仅仅是一个背景.有时,这个终端被称为"后推".
显然,这不再是CFG(类型-2).它包括类型1.但它是什么?真的输0了吗?
Prolog 中的Definite Clause Grammars dcg允许这种特殊的扩展.(为了避免误解,我在这里不考虑Prolog的完整扩展.即我假设终端来自有限的字母而不是任意的术语,我也不认为Prolog在DCG中允许的其他参数,这些参数也属于类型 - 已经0了.)
编辑:这是一种更简单的描述扩展的方法:添加到表单的CFG规则
A b -> <epsilon>
Run Code Online (Sandbox Code Playgroud) 如何在解析文本时传递状态(并在需要时更改它)!?
https://www.metalevel.at/prolog/dcg
这个例子正在计数..
不知道我应该如何通过初始状态。我是否必须将其作为调用参数或列表中的第一个元素来执行?每当我想使用状态时,我是否必须将状态(S)作为第一个目标?
======
假设我必须解析字符串“add item 5”。
如果状态是 "list" ,假设它应该打印 "5=>list"
如果“设置”则“5=>设置”
或者可能是更复杂的字符串“new list.add 5”...其中解析“new list”应设置 State=list,以便解析下一部分了解上下文,并且解释为“将 5 添加到列表” ” vs “添加 5 个到一组”。
不需要使用这些示例,我只是想弄清楚何时使用半上下文表示法以及如何将上下文作为第一个/顶部规则中的参数传递。
正如你所看到的,我很困惑,但这是我在互联网上能找到的唯一例子,序言文档一如既往地密集、简洁,而且不是很有帮助;(没有例子。
澄清 :
sent([X,Y],Ctx) --> make(X,Ctx), add(Y,Ctx).
make(V,Ctx) --> [make,V], {say(">make ~w |ctx: ~w", [V,Ctx])}.
add(V,_Ctx) --> [add,V], {say(">add ~w", [V])}.
Run Code Online (Sandbox Code Playgroud)
在这个例子中,我在每个级别传递上下文,即使我不在 add() 中使用它。我可以为 add() 删除它,但如果有子规则,我必须保留它。
我知道使用状态线程只需要在顶部规则中以及每当使用它时声明 Ctx