На прошлой неделе я получил анонс библиотеки для универсального парсинга, разрабатываемой
XRonos'ом, которая поддерживает, например, такие юз-кейсы (математический парсинг):
var spaces = Lp.OneOrMore(' ');
var digits = Lp.Digits();
var oper = Lp.Any("+", "-", "/", "*", "^").Id("Operator");
var openBracket = Lp.Char('(').Id("OpenBracket");
var closeBracket = Lp.Char(')').Id("CloseBracket");
// Выражения
var mainExpr = new LpmParser("mainExpr");
var exprInBrackets = new LpmParser("exprInBrackets");
var binaryExpr = new LpmParser("binaryExpr");
var operand = new LpmParser("operand");
// Рекурсия достигается за счёт отложенной инициализации реальных парсеров (см. свойство Parser), а комбинируются классы,
// которые потом вызывают Do, которая вызывает Parser.
//
operand.Parser = digits | exprInBrackets;
binaryExpr.Parser = (operand + spaces.Maybe()) + (oper + (spaces.Maybe() + operand)).OneOrMore();
mainExpr.Parser = (spaces | digits | binaryExpr | exprInBrackets).OneOrMore();
exprInBrackets.Parser = openBracket + mainExpr + closeBracket;
var results = mainExpr.Do("( ((5^6) + 5) / (3+4) )").ToArray();
Лично мне не понравилось то, что описание грамматики оказывается размазанной по коду. На вопрос, почему бы не описывать грамматику в формате какого-нибудь YACC'а с последующим... всем остальным, я получил резонный ответ, что для таких (практических, вообще говоря) задач как подсчет всех классов в фрагменте C#-кода это слишком трудоемко.
Это заставило меня пофантазировать, какой чемоданчик (toolkit) я бы хотел иметь, чтобы решать подобные задачи.
1. XML-based формат грамматик. Очень прост для использования в таких задачах, как "подсчет всех классов в фрагменте C#-кода", "колорирование кода", "вычисление выражений с размерностями". Не смотря на простоту, достаточно мощный для описания грамматик современных ЯП.
2. Приложение-редактор. Позволяет писать грамматики в вышеописанном формате, сохраняемые в файл, а также тестировать их. Для тестирования предлагается:
а. Окно-колорер (например, в процессе написания грамматики ЯП, хочется "видеть" ее на лету — грузишь в колорер исходник на этом ЯП и смотришь колорирование).
б. Окно-редактор. В качестве дополнения к грамматике можно написать простую имплементацию операторов, тех же +-/*-, на VB/C# и привязать к грамматике. Редактор собирает исходник посредством CaaS и дает возможность ввести выражение и "вычислить" его.
Разумеется, дополнения к грамматике тоже должны выгружаться вдобавок к XML-файлу, чтобы не писать исплементацию/цветовую схему по 10 раз.
3. Библиотека, которую можно подключить к проекту и которой можно подать на вход грамматику в строке или файле и заставить ее разбирать произвольный текст. Можно поддержать паттерн Visitor для RAD'ости.
Дисклеймер: от парсингов и грамматик я достаточно далек, поэтому допускаю широкий диапазон критики — от "описанное выше банально и сто раз реализовано" до "описанное выше труднореализуемо и никому не нужно".