Парсинг файлов проектов и пакетов с помощью Gold Parser --нужна помощь с 'IdList'



Я балуюсь с Object Pascal Engine (Роб ван ден Бринк), и кажется (за исключением нескольких незначительных и легко исправимых ошибок), что он работает для файлов Delphi unit.



Однако у него есть проблемы с разбором проекта (.ДНР) и пакет (.dpk) файлы; и проблема в основном сводится к различиям между материалом, который "использует" может иметь в блоках и проектах (а также то, что "содержит" предложение может иметь в пакетах).



Позвольте мне дать простой примеры:



В единице (.pas) file, предложение uses может быть примерно таким



uses
Windows,
Messages,
SysUtils,
Variants,
Classes,
Graphics,
Controls,
Forms,
Dialogs,
StdCtrls,
ExtCtrls,
ComCtrls;


Тогда как в проекте (.dpr) file



uses
Forms,
UnitDemoMain in 'UnitDemoMain.pas' {Form1},
SomeUnit in '..SomeUnit.pas',
SomeOtherUnit;


Тем не менее, та же функциональность (в названии 'contains') имеет место как:



contains
OneUnit in 'OneUnit.pas',
AnotherUnit in '..AnotherUnit.pas';


Проблема с файлом грамматики, который у меня есть (из приведенной выше ссылки), заключается в том, что он обрабатывает только самый простой случай (т. е. способ "использования" происходит в единичных файлах) и выдает ошибку для других.



Я предполагаю, что это сводится к тому, как "IdList" определяется в грамматический файл, который выглядит следующим образом:



<IdList> ::= <IdList> ',' <RefId>
| <RefId>


Тогда мой вопрос: Как я могу изменить это определение, чтобы оно могло обрабатывать другие альтернативы (как показано в файлах Project и Pacckage), т. е.:



UnitDemoMain in 'UnitDemoMain.pas' {Form1},
OneUnit in 'OneUnit.pas';
623   1  

1 ответ:

Я сам еще не использовал золотой пакет, но я довольно часто использовал Yacc; у него немного другая грамматическая структура, но принцип тот же.

Для начала я попробую изменить грамматику Delphi следующим образом:

Изменение

<UsesClause>        ::= USES <IdList> ';'
              | SynError

К

<UsesClause>        ::= USES <UnitList> ';'
              | SynError

И добавить

<UnitList>      ::= <UnitList> ',' <UnitRef>
              | <UnitRef>

<UnitRef>       ::= <RefID>
              | <RefID> IN <StringLiteral>
!                 | <RefID> in <StringLiteral> Comment Start <RefID> Comment End

Строка, которую я прокомментировал с помощью восклицательного знака, изначально предназначалась для обработки этой конструкции в вашем примере:

  UnitDemoMain in 'UnitDemoMain.pas' {Form1},

Однако, похоже, что золото Builder рассматривает символы с открытыми и закрытыми фигурными скобками, { }, как особый случай, который, по-видимому, не позволяет использовать их иначе, чем для окружения комментариев; я не смог найти способ использовать их как часть грамматического правила. Результатом этого изменения, как мы надеемся, должно быть то, что '{Form1}' просто игнорируется в качестве комментария, и пример конструкции соответствует предыдущему варианту (" IN StringLiteral").

Fwiw, золото выглядит довольно симпатичной упаковкой, за исключением нескольких проблемы, включая

  • Ограничение, упомянутое в ReadMe, что он может обрабатывать только символы 0..127 и

  • Его Parser Builder (V. 5. 2) жалуется при запуске с использованием грамматики образца D7, которая поставляется с ним (до моих предложенных изменений), на недопустимый символ запуска и лексическую ошибку в строке/состоянии 82. Может быть, я что-то упустил ...

Comments

    Ничего не найдено.