I am dabbling with the Object Pascal Engine (by Rob van den Brink) and it seems (except for a few minor and easily correctable errors) it works for Delphi unit files.
However, it has problems parsing Project (.dpr) and Package (.dpk) files; and the issue basically boils down to the differences between the stuff that 'uses' can have in units and projects (as well as what 'contains' clause can have in packages).
Let me give simple examples:
In a unit (.pas) file, the 'uses' clause can be something like this
uses
Windows,
Messages,
SysUtils,
Variants,
Classes,
Graphics,
Controls,
Forms,
Dialogs,
StdCtrls,
ExtCtrls,
ComCtrls;
whereas, in a Project (.dpr) file
uses
Forms,
UnitDemoMain in 'UnitDemoMain.pas' {Form1},
SomeUnit in '..\SomeUnit.pas',
SomeOtherUnit;
Yet, the same functionality (in the name of 'contains') occurs as:
contains
OneUnit in 'OneUnit.pas',
AnotherUnit in '..\AnotherUnit.pas';
The problem with the grammar file I have (from the above link) is that it only handles the most simple case (i.e. the way 'uses' occurs in unit files), and throws error for others.
I am guessing it boils down how 'IdList' is defined in the grammar file, which is this:
<IdList> ::= <IdList> ',' <RefId>
| <RefId>
My question, then, is: How do I alter this definition, so that it can handle other alternatives (as seen in Project and Pacckage files), i.e.:
UnitDemoMain in 'UnitDemoMain.pas' {Form1},
OneUnit in 'OneUnit.pas';
I haven't used the Gold package myself yet, but I have used Yacc quite a bit; that has a slightly different grammar layout but the principle is the same.
For starters I would try modifying the Delphi grammar as follows:
Change
<UsesClause> ::= USES <IdList> ';'
| SynError
to
<UsesClause> ::= USES <UnitList> ';'
| SynError
and add
<UnitList> ::= <UnitList> ',' <UnitRef>
| <UnitRef>
<UnitRef> ::= <RefID>
| <RefID> IN <StringLiteral>
! | <RefID> in <StringLiteral> Comment Start <RefID> Comment End
The line which I've commented out using the exclamation mark was initially intended to handle this construct in your example:
UnitDemoMain in 'UnitDemoMain.pas' {Form1},
However, it seems that Gold's Builder treats the open- and close-curly-brace characters, { }, as a special case which seems to prevent them being used as anything other than to surround comments; I've been unable to find a way of using them as part of a grammar rule. The result of this change should hopefully be that '{Form1}' is simply ignored as a comment, and the example construct matches the previous variant ("<RefID> IN StringLiteral") instead.
Fwiw, Gold looks quite a nice package, except for a few problems including
the restriction mentioned in the ReadMe that it can only handle characters 0..127 and
its Parser Builder (v.5.2) complains when running using the D7 sample grammar that comes with it (before my suggested changes) about an invalid start symbol and a lexical error on line/state 82. Maybe I've missed something ...
来源:https://stackoverflow.com/questions/35871440/parsing-project-and-package-files-using-gold-parser-help-needed-with-idlist