Сообщение Re[14]: [Nitra] Парсинг языков базирующихся на отсупах от 07.10.2014 15:14
Изменено 14.06.2015 7:34 Evgeny.Panasyuk
EP>Пример фильтра-препроцессора:
Пример без корутины-препроцессора, используя только возможности Boost.Spirit — через inherited attributes передаётся текущий уровень индентации:
Как я понимаю, если парсеры Nemerle/Nitra настолько же мощны — то тоже должно получиться.
LIVE DEMO
Пример без корутины-препроцессора, используя только возможности Boost.Spirit — через inherited attributes передаётся текущий уровень индентации:
/*******************************************************************************************/
root = statements(0u);
statements = *line_statement(lvl);
line_statement = indent(lvl) >> statement(lvl);
statement = (expression >> newline) | while_(lvl) | if_(lvl) | function(lvl);
expression = *alnum;
if_ = "if"_k >> +space >> expression >> block(lvl) >> indent(lvl) >> "else"_k >> block(lvl);
while_ = "while"_k >> +space >> expression >> block(lvl);
function = "def"_k >> +space >> expression >> '(' >> expression >> ')' >> block(lvl);
block = ':' >> ((newline >> compound(lvl)) | (+space >> statement(lvl)));
compound = omit[ indent_inc(lvl)[_a = _1] ] >> +line_statement(_a) >> indent_dec(lvl);
indent_inc = & repeat(lvl + 1, inf)[space][_val = phoenix::size(_1)];
indent_dec = & repeat(0u , lvl)[space];
indent = repeat(lvl )[space];
/*******************************************************************************************/
Кстати, как видно, при таком подходе помимо indent_inc, indent_dec понадобился ещё и indent.Как я понимаю, если парсеры Nemerle/Nitra настолько же мощны — то тоже должно получиться.
Тесты | |
| |
LIVE DEMO
full code | |
| |
Re[14]: [Nitra] Парсинг языков базирующихся на отсупах
EP>Пример фильтра-препроцессора:
Пример без корутины-препроцессора, используя только возможности Boost.Spirit — через inherited attributes передаётся текущий уровень индентации:
Как я понимаю, если парсеры Nemerle/Nitra настолько же мощны — то тоже должно получиться.
LIVE DEMO
UPD: Походу здесь indent_dec вообще не нужен — достаточно indent_inc и indent, надо будет проверить.
Пример без корутины-препроцессора, используя только возможности Boost.Spirit — через inherited attributes передаётся текущий уровень индентации:
/*******************************************************************************************/
root = statements(0u);
statements = *line_statement(lvl);
line_statement = indent(lvl) >> statement(lvl);
statement = (expression >> newline) | while_(lvl) | if_(lvl) | function(lvl);
expression = *alnum;
if_ = "if"_k >> +space >> expression >> block(lvl) >> indent(lvl) >> "else"_k >> block(lvl);
while_ = "while"_k >> +space >> expression >> block(lvl);
function = "def"_k >> +space >> expression >> '(' >> expression >> ')' >> block(lvl);
block = ':' >> ((newline >> compound(lvl)) | (+space >> statement(lvl)));
compound = omit[ indent_inc(lvl)[_a = _1] ] >> +line_statement(_a) >> indent_dec(lvl);
indent_inc = & repeat(lvl + 1, inf)[space][_val = phoenix::size(_1)];
indent_dec = & repeat(0u , lvl)[space];
indent = repeat(lvl )[space];
/*******************************************************************************************/
Кстати, как видно, при таком подходе помимо indent_inc, indent_dec понадобился ещё и indent.Как я понимаю, если парсеры Nemerle/Nitra настолько же мощны — то тоже должно получиться.
Тесты | |
| |
LIVE DEMO
full code | |
| |
UPD: Походу здесь indent_dec вообще не нужен — достаточно indent_inc и indent, надо будет проверить.