Graph 如何获得Rascal上下文无关语法的强连接组件

Graph 如何获得Rascal上下文无关语法的强连接组件,graph,context-free-grammar,rascal,connected-components,Graph,Context Free Grammar,Rascal,Connected Components,如问题所述,我希望能够将语法转换为一组强连接(仅限非终端)组件。我想通过从语法构造一个图来实现这一点,然后调用connectedcomponents函数。这就引出了真正的问题:如何构造具有以下类型边的有向图: For each A -> xBz where A,B in Non-terminals (N) and x and y in (sigma U N)*: construct an edge from A to B 是做类似的事情,这个内置,还是我必须完全实现自己?如果是这

如问题所述,我希望能够将语法转换为一组强连接(仅限非终端)组件。我想通过从语法构造一个图来实现这一点,然后调用connectedcomponents函数。这就引出了真正的问题:如何构造具有以下类型边的有向图:

For each A -> xBz where A,B in Non-terminals (N) and x and y in (sigma U N)*:
    construct an edge from A to B
是做类似的事情,这个内置,还是我必须完全实现自己?如果是这样的话,你能帮我开始吗?举例来说,通过演示如何从语法中仅获取终端、非终端和产生式规则?而不是仅仅通过机器可解析的语法数据结构

如果有更好的方法来找到组件,而不是构建图形,那当然也是一个很好的答案。 我希望这足够清楚,如果不清楚,请告诉我

编辑:我认为算法相对简单,我只是不知道如何在Rascal中实现这一点。下面是中算法的图片。
这里grammar.V是它的非终结符,P是它的产生式规则(不同的定义,因此不同的命名:s)

首先为语法获取语法,如下所示:

import Grammar;
gr = grammar(#YourTopNonterminal);
然后您可以使用这个库模块(带有关于如何提取依赖项的示例代码):

在相依符号之间有一个二元关系,如下所示:

rascal>symbolDependencies(g)
Graph[Symbol]: {
  <sort("A"),sort("B")>,
  <sort("B"),sort("C")>
}
理解循环遍历语法的所有规则,从中提取头
,然后在规则中查找所有符号
(可能由于正则表达式而嵌套),并为每一对创建一个元组

之后,您将开始分析和转换此关系,以获得强连接的组件。库模块
analysis::graphs::Graph
有一个示例函数,用于计算连接的组件(不是强连接的组件,因此您必须对此进行调整)

最后,将
sort(“a”)
之类的符号打印回一个漂亮的名称是很方便的,尤其是在非终端上有正则表达式的情况下(如*和+):

rascal>t=type(排序(“A”),();
类型[值]:类型(
排序(“A”),
())
流氓>“”
str:“A”

我还建议您使用
viz::Figure

可视化图形。您是否有可能对Kosaraju算法的实现感兴趣,该算法用于在有向图中查找强连接组件?
rascal>symbolDependencies(g)
Graph[Symbol]: {
  <sort("A"),sort("B")>,
  <sort("B"),sort("C")>
}
Graph[Symbol] symbolDependencies(Grammar g) =
  { <from,to> | /prod(Symbol from,[_*,Symbol elem,_*],_) := g, /Symbol to := elem}
rascal>import analysis::graphs::Graph;
ok
rascal>connectedComponents(symbolDependencies(g))
set[set[Symbol]]: {{
    sort("A"),
    sort("C"),
    sort("B")
  }}
rascal>t = type(sort("A"),());
type[value]: type(
  sort("A"),
  ())
rascal>"<t>"
str: "A"