Парсинг файлов проекта и пакета с использованием Gold Parser - требуется помощь с 'IdList'
Я работаю с движком Object Pascal Engine (от Роба ван ден Бринка), и кажется (за исключением нескольких незначительных и легко исправляемых ошибок) он работает для файлов модулей Delphi.
Однако возникают проблемы при разборе файлов Project (.dpr) и Package (.dpk); и проблема в основном сводится к различиям между тем, что "использует" может иметь в юнитах и проектах (а также тем, что "содержит" может иметь в пакетах).
Позвольте мне привести простые примеры:
В модульном (.pas) файле предложение 'users' может выглядеть примерно так
uses
Windows,
Messages,
SysUtils,
Variants,
Classes,
Graphics,
Controls,
Forms,
Dialogs,
StdCtrls,
ExtCtrls,
ComCtrls;
тогда как в файле проекта (.dpr)
uses
Forms,
UnitDemoMain in 'UnitDemoMain.pas' {Form1},
SomeUnit in '..\SomeUnit.pas',
SomeOtherUnit;
Тем не менее, такая же функциональность (во имя "содержит") происходит как:
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';
1 ответ
Я еще не пользовался пакетом Gold, но довольно часто использовал 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},
Однако, похоже, что Gold's Builder рассматривает символы с открытой и закрытой фигурной скобкой { }, как особый случай, который, кажется, не позволяет использовать их как что-либо кроме окружения комментариев; Я не смог найти способ использовать их как часть правила грамматики. Мы надеемся, что результатом этого изменения будет то, что '{Form1}' просто игнорируется как комментарий, а примерная конструкция соответствует предыдущему варианту ("
Кстати, Gold выглядит довольно неплохо, за исключением нескольких проблем, в том числе
ограничение, упомянутое в ReadMe, заключается в том, что он может обрабатывать только символы 0..127 и
его Parser Builder (v.5.2) жалуется при запуске с использованием прилагаемой к нему образцовой грамматики D7 (до предложенных мной изменений) о недопустимом символе начала и лексической ошибке в строке / состоянии 82. Возможно, я что-то пропустил...