BNF грамматика, которая имеет разделы без окончания?
Мне нужно разобрать простой проприетарный язык, который я не проектировал, поэтому я не могу изменить язык. Мне нужны результаты в C#, поэтому я использую TinyPG, потому что он очень прост в использовании и не требует внешних библиотек для запуска парсера. TinyPG генерирует простой парсер LL(1).
Проблема, которая у меня сейчас есть, связана с тем, как язык делит файл на разделы. В нем есть разделы для различных типов переменных, установки их начальных значений, определений уравнений и т. Д. Я забочусь только о разделах, которые объявляют переменные, поэтому я хотел бы просто игнорировать остальные. Я не знаю всех правил для других разделов и не хочу их выяснять. Они могут рассматриваться как комментарии.
Вот пример кода:
PARAMETER
Density AS REAL
CrossSectionalArea AS REAL
SET # Parameter values
T101.FO := "SimpleEventFOI::dummy";
T101.CrossSectionalArea := 1 ; # m2
EQUATION
OutSingleInt = SingleInt;
OutArrayInt = ArrayInt;
Я забочусь о разделах PARAMETER и SET, но не о разделе EQUATION. Как видите, проблема в том, что в этих разделах нет маркеров END. Поэтому я не могу понять, как сказать грамматике, что раздел заканчивается, когда вы получаете другое ключевое слово, но новое ключевое слово может начать новый раздел. В моих попытках новое ключевое слово начала раздела используется, чтобы закрыть старый раздел.
Здесь гораздо больше разделов, чем я перечислил, некоторые из которых меня волнуют, а некоторые нет. Кажется, они делятся на два типа: "Похоже на ПАРАМЕТР", у которых нет точек с запятой в конце операторов, и "Похоже на УРАВНЕНИЕ", которые имеют. Этот язык не учитывает регистр или пробелы. Разделы могут быть в любом порядке. (например, SET, EQUATION, PARAMETER) Помимо комментариев, все это можно записать в одну строку.
В настоящее время я обхожу это с помощью регулярного выражения, чтобы найти интересующие меня разделы, и только передаю их парсеру, но у меня также возникают проблемы с созданием регулярного выражения, которое работает во всех случаях, но не случайно подбирает ключевые слова в комментариях. Я могу в конечном итоге просто расширить этот обходной путь, чтобы решить его проблемы, но было бы лучше решить проблему непосредственно в грамматике. Возможно, это просто не язык LL(1).
1 ответ
Я попробовал следующий код tpg, он может разобрать ваш пример. Похоже, TinyPG не может различить ключевое слово и идентификатор, поэтому я немного взломал идентификатор.
//Tiny Parser Generator v1.3
//Copyright © Herre Kuijpers 2008-2012
<% @TinyPG Namespace="Test" %>
PARAMETER -> @"PARAMETER";
SET -> @"SET";
EQUATION -> @"EQUATION";
AS -> @"AS";
ID -> @"\b(?!(PARAMETER|SET|EQUATION)\b)([a-zA-Z]\w+)";
DOT -> @"\.";
EQ -> @":=";
EXPR -> @"\d|""[^""]*""";
END -> @";";
[Skip] WS -> @"\s+|#[^\r\n]+";
EQDECL -> @"\b(?!(PARAMETER|SET|EQUATION)\b)([^#;]+)";
Equations -> EQUATION (EQDECL END)*;
Parameters -> PARAMETER ParamDecl*;
ParamDecl -> ID AS ID;
Sets -> SET SetDecl*;
SetDecl -> FullId EQ EXPR END;
FullId -> ID DOT ID;
Section -> Equations | Parameters | Sets;
Start -> Section*;