2015-06-04 4 views
2

Мне нужно разобрать простой проприетарный язык, который я не разрабатывал, поэтому я не могу изменить язык. Мне нужны результаты на C#, поэтому я использовал TinyPG, потому что он настолько прост в использовании и не требует использования внешних библиотек для запуска анализатора. TinyPG генерирует простой парсер LL (1).BNF-грамматика, которая имеет разделы без конца?

Проблема, с которой я сталкиваюсь, связана с тем, как язык делит файл на разделы. Он имеет разделы для разных видов переменных, устанавливая их начальные значения, определения уравнений и т. Д. Меня интересуют только разделы, объявляющие переменные, поэтому я хотел бы просто игнорировать остальные. Я не знаю всех правил для других разделов и не хочу их вычислять. Они могут рассматриваться как комментарии.

Вот пример кода:

PARAMETER 
    Density    AS REAL 
    CrossSectionalArea AS REAL 

SET # Parameter values 
    T101.FO     := "SimpleEventFOI::dummy"; 
    T101.CrossSectionalArea := 1 ; # m2 

EQUATION 
    OutSingleInt = SingleInt; 
    OutArrayInt = ArrayInt; 

Я забочусь о секциях параметра и установить, но не раздел УРАВНЕНИЯ. Как вы можете видеть, проблема в том, что эти разделы не имеют маркеров END. Поэтому я не могу понять, как сказать грамматике, что раздел заканчивается, когда вы получаете другое ключевое слово, но что новое ключевое слово может начать новый раздел. В моих попытках новое ключевое ключевое слово раздела начинается, чтобы закрыть старый раздел.

Есть много других разделов, чем я перечислял здесь, некоторые из которых меня волнуют, некоторые - нет. Кажется, что они делятся на два типа: «Похоже, PARAMETER», которые не имеют точек с запятой в конце высказываний, и «Походит на УРАВНЕНИЕ», которые делают. Этот язык не является случайным или непрозрачным. Секции могут быть в любом порядке. (например, SET, EQUATION, PARAMETER). Помимо комментариев, все это может быть написано на одной строке.

В настоящее время я обойду это, используя регулярное выражение, чтобы найти разделы, которые меня интересуют, и только кормить их парсером, но у меня также возникают проблемы с регулярным выражением, которое работает в все случаи, но не случайно забирают ключевые слова в комментариях. Я могу в конечном итоге просто расширить это обходное решение, чтобы решить его проблемы, но было бы лучше решить проблему непосредственно в грамматике. Возможно, это не язык LL (1).

+1

В вашем примере это выглядит как «SET» - это конечный маркер для «PARAMETER»; и что «EQUATION» является конечным маркером для «SET» и что <> является конечным маркером для «EQUATION». Разумеется, вам нужно начать с спецификации языка, а не с примера ... важно, чтобы вы не полагались на синтаксическое совпадение в ваших образцовых данных. [BTW: Он определенно выглядит «LL (1)» - возможно, можно даже утверждать, что он находится в регулярном подмножестве LL (1)] – aSteve

+0

@aSteve Но, возможно, они являются необязательными ... Не могли бы вы создать действительный файл без SET? – xanatos

+2

Без спецификации грамматики файла, который вы хотите проанализировать, вы никогда не сможете узнать ответ на свой вопрос. Вы могли догадаться, и вам может повезти - никаких гарантий. Спецификация не обязательно должна быть BNF - например, исходный код программы, в которой записаны все файлы, подлежащие анализу, будет достаточным ... или могут быть адекватные детали в неофициальной документации. Примером может служить не спецификация. :) – aSteve

ответ

0

Я пробовал следующий код tpg, он может проанализировать ваш пример. Looks 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*; 
+0

Спасибо за это, но порядок раздела не гарантируется. Этот пример не работает, если вы немного смешаете разделы. (Я должен был сделать это в моем примере.) Итак, если разделы PARAMETER EQUATION SET tpg не будут правильно анализировать. Он будет претендовать на синтаксический анализ, но SET все втянут EQUATION. – Jim

+0

Ах, если каждое уравнение заканчивается на ';' и если параметры всегда декларируют первый раздел, его можно изменить, чтобы он работал. – Diryboy

+0

Есть идея. Секции, которые я действительно не хочу анализировать, похоже, имеют утверждения, заканчивающиеся на «;» или «END» – Jim

 Смежные вопросы

  • Нет связанных вопросов^_^