我正在讨论Object Pascal Engine(Rob van den Brink),看起来(除了一些轻微且容易纠正的错误)它适用于Delphi单元文件。
但是,它在解析Project( .dpr)和Package( .dpk)文件时遇到问题;而这个问题基本上归结为“使用”和“使用”之间的差异。可以有单位和项目(以及包含的'包含'子句)。
让我举一些简单的例子:
在单位(.pas)文件中,'使用'子句可以是这样的
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';
答案 0 :(得分:2)
我自己还没有使用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}”被简单地忽略为注释,而示例构造与之前的变体(“&lt; RefID&gt; IN StringLiteral”)相匹配。
Fwiw,Gold除了包括
在内的一些问题外,看起来还不错自述文件中提到的限制,它只能处理字符0..127和
它的Parser Builder(v.5.2)在使用它附带的D7示例语法(在我建议的更改之前)运行时抱怨无效的开始符号和行/状态82上的词汇错误。也许我'我错过了什么...