Здравствуйте, VladD2, Вы писали:
VD>Что-то я не могу понять, что за проблема такая. Можно пояснить на примере?
под терминальным символом я понимаю:
//именованный: spaces
spaces = ' '*;
//неименованные: '*' и '/'
mulOrDiv : int = simplExpr (('*' / '/') spaces simplExpr)*;
проблема была в следующем:
в парсере не происходило добавления терминальных символов к АСТ, а я брал за терминальные символы участки исходного текста, разделённые НЕтерминальными символами, в результате в списке терминальных символов, находилось:
"10 " вместо "10" и " "
и "+ " вместо "+" и " "
проблема была в следующем:
при парсинге или даже при формировании грамматики терминальные символы не обрабатывались как Rule.Capture
более того у них не сохранялись имена (spaces, digit..) и вообще при оптимизации грамматики именнованые "инлайнились" и становились неименованными.
В новой ревизии я добавил сохранение имени для (spaces, digit..), а также добавление именованных терминальным символов в АСТ.
Мне кажется получился уже довольно функциональный код. Наверное можно строить и сложные грамматики. пока только одно ограничение: не использовать неименнованные терминальные символы:
grammar
{
any = ['\u0000'..'\uFFFF'];
digit = ['0'..'9']+;
spaces = ' '*;
mulOp = '*';
divOp = '/';
sumOp = '+';
subOp = '-';
leftBrace = '(';
rightBrace = ')';
num : int = digit + spaces;
unaryMinus : int = subOp spaces simplExpr;
parenthesesExpr : int = leftBrace spaces sumOrSub rightBrace spaces;
simplExpr : int = num / parenthesesExpr / unaryMinus;
mulOrDiv : int = simplExpr ((mulOp / divOp) spaces simplExpr)*;
sumOrSub : int = mulOrDiv ((sumOp / subOp) spaces mulOrDiv )*;
start : int = spaces sumOrSub !any;
}
в ближайшее время займусь рефакторингном того сумбура, который я внёс))