使用 Gold Parser 解析项目和包文件 -- 'IdList' 需要帮助
Parsing Project and Package files using Gold Parser --help needed with 'IdList'
我正在研究 Object Pascal Engine(Rob van den Brink 着),它似乎(除了一些小的和容易纠正的错误)它适用于 Delphi 单元文件。
但是解析Project(.dpr)和Package(.dpk)文件时出现问题;问题基本上归结为 'uses' 可以在单元和项目中包含的内容之间的差异(以及 'contains' 子句在包中可以包含的内容)。
让我举个简单的例子:
在单元 (.pas) 文件中,'uses' 子句可以是这样的
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' 的名义)出现为:
contains
OneUnit in 'OneUnit.pas',
AnotherUnit in '..\AnotherUnit.pas';
我的语法文件的问题(来自上面link)是它只处理最简单的情况(即'uses'出现在单元文件中的方式),并抛出错误对于其他人。
我猜它归结为 'IdList' 是如何在语法文件中定义的,它是这样的:
<IdList> ::= <IdList> ',' <RefId>
| <RefId>
那么,我的问题是:我如何更改此定义,以便它可以处理其他替代方案(如 Project 和 Pacckage 文件中所示),即:
UnitDemoMain in 'UnitDemoMain.pas' {Form1},
OneUnit in 'OneUnit.pas';
我自己还没有用过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 的 Builder 似乎将左花括号和右花括号字符 { } 视为一种特殊情况,这似乎可以防止它们被用作除了围绕注释之外的任何其他用途;我一直无法找到将它们用作语法规则一部分的方法。此更改的结果应该是“{Form1}”作为注释被简单地忽略,并且示例构造与先前的变体(“ IN StringLiteral”)相匹配。
顺便说一句,Gold 看起来很不错,除了一些问题,包括
ReadMe中提到的限制只能处理字符0..127和
它的 Parser Builder (v.5.2) 在 运行 使用它附带的 D7 示例语法时(在我建议的更改之前)抱怨无效的开始符号和词法错误line/state82.也许我漏掉了什么...
我正在研究 Object Pascal Engine(Rob van den Brink 着),它似乎(除了一些小的和容易纠正的错误)它适用于 Delphi 单元文件。
但是解析Project(.dpr)和Package(.dpk)文件时出现问题;问题基本上归结为 'uses' 可以在单元和项目中包含的内容之间的差异(以及 'contains' 子句在包中可以包含的内容)。
让我举个简单的例子:
在单元 (.pas) 文件中,'uses' 子句可以是这样的
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' 的名义)出现为:
contains
OneUnit in 'OneUnit.pas',
AnotherUnit in '..\AnotherUnit.pas';
我的语法文件的问题(来自上面link)是它只处理最简单的情况(即'uses'出现在单元文件中的方式),并抛出错误对于其他人。
我猜它归结为 'IdList' 是如何在语法文件中定义的,它是这样的:
<IdList> ::= <IdList> ',' <RefId>
| <RefId>
那么,我的问题是:我如何更改此定义,以便它可以处理其他替代方案(如 Project 和 Pacckage 文件中所示),即:
UnitDemoMain in 'UnitDemoMain.pas' {Form1},
OneUnit in 'OneUnit.pas';
我自己还没有用过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 的 Builder 似乎将左花括号和右花括号字符 { } 视为一种特殊情况,这似乎可以防止它们被用作除了围绕注释之外的任何其他用途;我一直无法找到将它们用作语法规则一部分的方法。此更改的结果应该是“{Form1}”作为注释被简单地忽略,并且示例构造与先前的变体(“
顺便说一句,Gold 看起来很不错,除了一些问题,包括
ReadMe中提到的限制只能处理字符0..127和
它的 Parser Builder (v.5.2) 在 运行 使用它附带的 D7 示例语法时(在我建议的更改之前)抱怨无效的开始符号和词法错误line/state82.也许我漏掉了什么...