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*;
Другие вопросы по тегам