Доступ к поддереву регулярного выражения в 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], кажется, не правильный путь.

Спасибо за любую помощь.

2 ответа

Решение

Вероятно, проще всего сделать, если вам не нужно определять списки так, как вы делали выше, с отдельной головой и хвостом, - это использовать встроенную в Rascal конструкцию с разделенным списком, например, так:

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

(Если вам нужна отдельная голова и хвост, см. Ответ Юргена ниже. Вы можете использовать эту же запись там же.)

Это определяет список из 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] не работает, хотя это может показаться логичным: здесь возвращается результат мета-представления вместо фактического первого элемента списка, но мы можем перебрать элементы списка и выбрать только первый:

if (CHAR e <- v) println(e); 
b
ok
Другие вопросы по тегам