访问parsetree中的regexp子树

时间:2015-10-14 11:26:25

标签: rascal

我有以下Rascal模块:

ALTER IGNORE TABLE gsp ADD UNIQUE KEY (dt); 

我的问题是如何在解析某些内容之后找到module foo import IO; import ParseTree; extend lang::std::Layout; lexical CHAR = [ab]; start syntax CharList = CHAR hd (',' CHAR)+ tl ';'; 部分的各个元素。 E.g:

tl

现在我如何访问rascal>import foo; ok rascal>pt = parse(#start[CharList], "a, b;"); start[CharList]: `a, b;` Tree: appl(... rascal>pt.top.tl; (',' CHAR)+: `, b` Tree: appl(regular(... 元素? pt.top.tl [0]似乎不是正确的方法。

感谢您的帮助。

2 个答案:

答案 0 :(得分:3)

除非你需要以上面单独的头尾方式完成列表定义列表,否则最容易做的事情就是使用Rascal的内置分隔列表构造,如下所示:

start syntax CharList = {CHAR ","}+ chars ';';

(如果您需要单独的头部和尾部,请参阅下面的Jurgen的答案。您也可以在那里使用相同的表示法。)

这定义了一个包含1个或更多(由于+)逗号分隔的CHAR的列表。如果您需要0或更多,则使用*。 Rascal允许您遍历单独的列表,因此您可以像这样获取字符:

rascal> chars = [c | c <- pt.top.chars ];

对于您的示例中的列表,这给了我以下内容:

list[CHAR]: [appl(
    prod(
      lex("CHAR"),
      [\char-class([range(97,98)])],
      {}),
    [char(97)])[
    @loc=|unknown:///|(0,1,<1,0>,<1,1>)
  ],appl(
    prod(
      lex("CHAR"),
      [\char-class([range(97,98)])],
      {}),
    [char(98)])[
    @loc=|unknown:///|(3,1,<1,3>,<1,4>)
  ]]

如果您想更轻松地查看它们或使用字符串值执行某些操作,您也可以将它们转换为字符串:

rascal>charsAsStrings = ["<c>" | c <- pt.top.chars ];
list[str]: ["a","b"]

答案 1 :(得分:1)

首先,它可以这样写,以便更容易:

start syntax CharList =  CHAR hd "," {CHAR ","}+ tl ';';

然后:

rascal>t = parse(#start[CharList], "a,b;");
start[CharList]: `a,b;`
rascal>u = t.top;
CharList: `a,b;`
rascal>v = u.tl;
{CHAR  "," }+: `b`

v [0]被破坏了,虽然这看起来很合乎逻辑,它返回元表示的prod而不是列表的实际第一个元素,但是我们可以迭代列表上的元素并仅选择第一个:

if (CHAR e <- v) println(e); 
b
ok