访问解析树中的正则表达式子树
accessing regexp subtree in parsetree
我有以下 Rascal 模块:
module foo
import IO;
import ParseTree;
extend lang::std::Layout;
lexical CHAR = [ab];
start syntax CharList = CHAR hd (',' CHAR)+ tl ';';
我的问题是如何在解析某些内容后到达 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(...
现在如何访问 , b
元素?
pt.top.tl[0]好像方法不对
感谢您的帮助。
可能最简单的做法是使用 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"]
首先可以这样写,这样更简单:
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] 被破坏了,虽然这在这里看起来合乎逻辑 returns 元表示的 prod 而不是列表的实际第一个元素,但我们可以迭代列表中的元素select 只有第一个:
if (CHAR e <- v) println(e);
b
ok
我有以下 Rascal 模块:
module foo
import IO;
import ParseTree;
extend lang::std::Layout;
lexical CHAR = [ab];
start syntax CharList = CHAR hd (',' CHAR)+ tl ';';
我的问题是如何在解析某些内容后到达 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(...
现在如何访问 , b
元素?
pt.top.tl[0]好像方法不对
感谢您的帮助。
可能最简单的做法是使用 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"]
首先可以这样写,这样更简单:
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] 被破坏了,虽然这在这里看起来合乎逻辑 returns 元表示的 prod 而不是列表的实际第一个元素,但我们可以迭代列表中的元素select 只有第一个:
if (CHAR e <- v) println(e);
b
ok