请教 Delphi 帮助中的 Object Pascal EBNF 语法中,符号'/'的含义 (200分)

  • 主题发起人 主题发起人 hlsl
  • 开始时间 开始时间
H

hlsl

Unregistered / Unconfirmed
GUEST, unregistred user!
我最近在写一个语法解析器(Parser),参考了Delphi帮助中的Object Pascal语法.
其中有几个符号我不是很清楚它的意思,因为似乎是简写,不是标准的EBNF表示法.
比如: IdentList -> Ident/','...
我把符号 '/' 理解为"如果有的话", 而符号 '...'理解为重复.那么整个的意思就是:
首先是一个Ident,如果后面跟一个逗号','的话,那么继续重复.

如果这个比较好说,那么下面这几个就把我弄糊涂了:

ClassFieldList -> (ClassVisibility ObjFieldList)/';'... 主要是这个
ObjFieldList -> (IdentList ':' Type)/';'...
IdentList -> Ident/','...

ClassFieldList 定义中的';'和前面的','意思应该是一样的,但是看下面的ObjFieldList,也是一样! 那么问题就来了.比如着条语句:
public
FObjField1, FObjField2: Char;
public
procedure ProcA;


其中的public是定义中的ClassVisibility, FObjField1, FObjField2是定义中的 IdentList , Char 是定义中的 Type ,那么最后的分号';' 是算ObjFieldList的还是ClassFieldList的呢?
关键问题是,不管是谁的,那么就要重复(...)。如果是ObjFieldList的,那么很明显后面没有了。如果是ClassFieldList,结果也是一样。因为后面有 procedure 这个关键字,所以后面是应该ClassMethodList了。这里就要解决一个“像前看”的问题。

我的问题就是:这个表达法中的/';'...是不是表示我前面开头说的意思呢?
 
不知道您看的是哪个帮助主题,我看了 Delphi Language Reference - Object Pascal
grammar 的范式,没有'/'的。

FormalParm -> [VAR | CONST | OUT] Parameter
Parameter -> IdentList [':' ([ARRAY OF] SimpleType | STRING | FILE)]
-> Ident ':' SimpleType '=' ConstExpr
 
就是DELPHI帮助中的,也就是你看的那个。仔细找一下,有很多的都是带有这个 '/' 符号的,比如你找一下我提到的两个
 
喔,对了,我看的是DELPHI5中的。不过6、7的好象都是一样的
 
我也没看到有
 
public FObjField1, FObjField2: Char;
;是ClassFieldList的,如果下文是ClassVisibility 或 End
是ObjFieldList的,如果下文是IdentList

好象不规范
 
TO: 没有看到的朋友,其实有很多啊,是不是没有看仔细?
比如第一页下面的:
ArrayConstant -> '(' TypedConstant/','... ')'
RecordConstant -> '(' RecordFieldConstant/';'... ')'

结尾倒数第9行的:
IdentList -> Ident/','...

不都是带‘/’这个符号的吗?


TO: jackchin
不知道你说的不规范是指什么?
就声明语法而言,这里的语法是允许各种组合的,比如:
...
protected
FVarA: Byte;
protected
FVarB: String

FVarC, FVarD: Char;
procedure proc1;
...

甚至每个声明前面加 ClassVisibility 都可以的。唯一不允许的是,声明方法以后再声明变量。也就是变量要在方法前面声明。
 
public FObjField1, FObjField2: Char;
-----------------------------------------------------
对这个实例我的理解是,
';' 是属于ClassFieldList的,如果下文是ClassVisibility 或 END关键字,否则
';' 是属于ObjFieldList的

不知道是否符合语法定义的规范
另外,Pascal END关键字前的';'是可以省略的
 
在类的定义里面,END前的分号是不能省略的,
像这种:
TObj = class
public
procedure A
end;
A 后面没有分号,是不行的。

另外,如果按照你前面说的上下文的方法来判断是没法做的,因为是递归下降分析法,在ObjFieldList里面就要解决;的归属问题。而在ObjFieldList是不能仅仅针对ClassFieldList来做判断的。因为还涉及到其它的语法元素啊。
还有就是,如果下文是方法声明呢?其实不管是什么,PASCAL的语法说“语句要以;结尾”,不应该扔到后面来说吧?

我越来越对这个'/'糊涂了,想必是DELPHI的文档工程师偷懒简写,或者是因为无法定义而在编译器里面做特殊上下文判断处理的。

另外,DELPHI帮助的语法定义里面好象有很多错误。比如:
ProcedureHeading -> PROCEDURE Ident [FormalParameters]
按照这样的定义,类似 procedure TForm1.FormCreate 这种方法头就没法解释了。因为Ident的定义是一个单词。也许应该是Designator或者又是特殊处理吧?
 
有人说没有见过这个符号,那么我把这个语法的全文贴上来,说明:是DELPHI5的帮助中的。



Goal -> (Program | Package | Library | Unit)

Program -> [PROGRAM Ident ['(' IdentList ')'] ';']
ProgramBlock '.'

Unit -> UNIT Ident ';'
InterfaceSection
ImplementationSection
[InitSection]
END '.'

Package -> PACKAGE Ident ';'
[RequiresClause]
[ContainsClause]
END '.'

Library -> LIBRARY Ident ';'
ProgramBlock '.'

ProgramBlock -> [UsesClause]
Block

UsesClause -> USES IdentList ';'
InterfaceSection -> INTERFACE
[UsesClause]
[InterfaceDecl]...

InterfaceDecl -> ConstSection
-> TypeSection
-> VarSection
-> ExportedHeading

ExportedHeading -> ProcedureHeading ';' [Directive]
-> FunctionHeading ';' [Directive]

ImplementationSection -> IMPLEMENTATION
[UsesClause]
[DeclSection]...

Block -> [DeclSection]
CompoundStmt

DeclSection -> LabelDeclSection
-> ConstSection
-> TypeSection
-> VarSection
-> ProcedureDeclSection

LabelDeclSection -> LABEL LabelId
ConstSection -> CONST (ConstantDecl ';')...
ConstantDecl -> Ident '=' ConstExpr
-> Ident ':' TypeId '=' TypedConstant

TypeSection -> TYPE (TypeDecl ';')...
TypeDecl -> Ident '=' Type
-> Ident '=' RestrictedType

TypedConstant -> (ConstExpr | ArrayConstant | RecordConstant)
ArrayConstant -> '(' TypedConstant/','... ')'
RecordConstant -> '(' RecordFieldConstant/';'... ')'
RecordFieldConstant -> Ident ':' TypedConstant
Type -> TypeId
-> SimpleType
-> StrucType
-> PointerType
-> StringType
-> ProcedureType
-> VariantType
-> ClassRefType

RestrictedType -> ObjectType
-> ClassType
-> InterfaceType

ClassRefType -> CLASS OF TypeId
SimpleType -> (OrdinalType | RealType)
RealType -> REAL48
-> REAL
-> SINGLE
-> DOUBLE
-> EXTENDED
-> CURRENCY
-> COMP

OrdinalType -> (SubrangeType | EnumeratedType | OrdIdent)
OrdIdent -> SHORTINT
-> SMALLINT
-> INTEGER
-> BYTE
-> LONGINT
-> INT64
-> WORD
-> BOOLEAN
-> CHAR
-> WIDECHAR
-> LONGWORD
-> PCHAR

VariantType -> VARIANT
-> OLEVARIANT

SubrangeType -> ConstExpr '..' ConstExpr
EnumeratedType -> '(' IdentList ')'
StringType -> STRING
-> ANSISTRING
-> WIDESTRING
-> STRING '[' ConstExpr ']'

StrucType -> [PACKED] (ArrayType | SetType | FileType | RecType)
ArrayType -> ARRAY ['[' OrdinalType/','... ']'] OF Type
RecType -> RECORD [FieldList] END
FieldList -> FieldDecl/';'... [VariantSection] [';']
FieldDecl -> IdentList ':' Type
VariantSection -> CASE [Ident ':'] TypeId OF RecVariant/';'...
RecVariant -> ConstExpr/','... ':' '(' [FieldList] ')'
SetType -> SET OF OrdinalType
FileType -> FILE OF TypeId

PointerType -> '^' TypeId
ProcedureType -> (ProcedureHeading | FunctionHeading) [OF OBJECT]
VarSection -> VAR (VarDecl ';')...
VarDecl -> IdentList ':' Type [(ABSOLUTE (Ident | ConstExpr)) | '=' ConstExpr]
Expression -> SimpleExpression [RelOp SimpleExpression]...
SimpleExpression -> ['+' | '-'] Term [AddOp Term]...
Term -> Factor [MulOp Factor]...
Factor -> Designator ['(' ExprList ')']
-> '' Designator
-> Number
-> String
-> NIL
-> '(' Expression ')'
-> NOT Factor
-> SetConstructor
-> TypeId '(' Expression ')'

RelOp -> '>'
-> '<'
-> '<='
-> '>='
-> '<>'
-> IN
-> IS
-> AS

AddOp -> '+'
-> '-'
-> OR
-> XOR

MulOp -> '*'
-> '/'
-> DIV
-> MOD
-> AND
-> SHL
-> SHR

Designator -> QualId ['.' Ident | '[' ExprList ']' | '^']...
SetConstructor -> '[' [SetElement/','...] ']'
SetElement -> Expression ['..' Expression]
ExprList -> Expression/','...
Statement -> [LabelId ':'] [SimpleStatement | StructStmt]
StmtList -> Statement/';'...
SimpleStatement -> Designator ['(' ExprList ')']
-> Designator ':=' Expression
-> INHERITED
-> GOTO LabelId

StructStmt -> CompoundStmt
-> ConditionalStmt
-> LoopStmt
-> WithStmt

CompoundStmt -> BEGIN StmtList END
ConditionalStmt -> IfStmt
-> CaseStmt

IfStmt -> IF Expression THEN Statement [ELSE Statement]
CaseStmt -> CASE Expression OF CaseSelector/';'... [ELSE Statement] [';'] END
CaseSelector -> CaseLabel/','... ':' Statement
CaseLabel -> ConstExpr ['..' ConstExpr]
LoopStmt -> RepeatStmt
-> WhileStmt
-> ForStmt

RepeatStmt -> REPEAT Statement UNTIL Expression
WhileStmt -> WHILE Expression DO Statement
ForStmt -> FOR QualId ':=' Expression (TO | DOWNTO) Expression DO Statement
WithStmt -> WITH IdentList DO Statement
ProcedureDeclSection -> ProcedureDecl
-> FunctionDecl

ProcedureDecl -> ProcedureHeading ';' [Directive]
Block ';'

FunctionDecl -> FunctionHeading ';' [Directive]
Block ';'

FunctionHeading -> FUNCTION Ident [FormalParameters] ':' (SimpleType | STRING)
ProcedureHeading -> PROCEDURE Ident [FormalParameters]
FormalParameters -> '(' FormalParm/';'... ')'
FormalParm -> [VAR | CONST | OUT] Parameter
Parameter -> IdentList [':' ([ARRAY OF] SimpleType | STRING | FILE)]
-> Ident ':' (SimpleType | STRING) '=' ConstExpr

Directive -> CDECL
-> REGISTER
-> DYNAMIC
-> VIRTUAL
-> EXPORT
-> EXTERNAL
-> FAR
-> FORWARD
-> MESSAGE
-> OVERRIDE
-> OVERLOAD
-> PASCAL
-> REINTRODUCE
-> SAFECALL
-> STDCALL

ObjectType -> OBJECT [ObjHeritage] [ObjFieldList] [MethodList] END
ObjHeritage -> '(' QualId ')'
MethodList -> (MethodHeading [';' VIRTUAL])/';'...
MethodHeading -> ProcedureHeading
-> FunctionHeading
-> ConstructorHeading
-> DestructorHeading

ConstructorHeading -> CONSTRUCTOR Ident [FormalParameters]
DestructorHeading -> DESTRUCTOR Ident [FormalParameters]
ObjFieldList -> (IdentList ':' Type)/';'...
InitSection -> INITIALIZATION StmtList [FINALIZATION StmtList] END
-> BEGIN StmtList END
-> END

ClassType -> CLASS [ClassHeritage]
[ClassFieldList]
[ClassMethodList]
[ClassPropertyList]
END

ClassHeritage -> '(' IdentList ')'
ClassVisibility -> [PUBLIC | PROTECTED | PRIVATE | PUBLISHED]
ClassFieldList -> (ClassVisibility ObjFieldList)/';'...
ClassMethodList -> (ClassVisibility MethodList)/';'...
ClassPropertyList -> (ClassVisibility PropertyList ';')...
PropertyList -> PROPERTY Ident [PropertyInterface] PropertySpecifiers
PropertyInterface -> [PropertyParameterList] ':' Ident
PropertyParameterList -> '[' (IdentList ':' TypeId)/';'... ']'

PropertySpecifiers -> [INDEX ConstExpr]
[READ Ident]
[WRITE Ident]
[STORED (Ident | Constant)]
[(DEFAULT ConstExpr) | NODEFAULT]
[IMPLEMENTS TypeId]

InterfaceType -> INTERFACE [InterfaceHeritage]
[ClassMethodList]
[ClassPropertyList]
END

InterfaceHeritage -> '(' IdentList ')'
RequiresClause -> REQUIRES IdentList... ';'
ContainsClause -> CONTAINS IdentList... ';'
IdentList -> Ident/','...
QualId -> [UnitId '.'] Ident
TypeId -> [UnitId '.'] <type-identifier>
Ident -> <identifier>
ConstExpr -> <constant-expression>
UnitId -> <unit-identifier>
LabelId -> <label-identifier>
Number -> <number>
String -> <string>

 
译文
Object Pascal文法
(译文略)。

相关主题
语法元素:概述
使用Object Pascal

编者注
Object Pascal文法涉及的内容不宜作中文翻译(如果用中文描述则会失去很多原意),因此只保留原文。

当前文法本身又具有一定的行文规范。下面举例说明:

Goal -> (Program | Package | Library | Unit)

Program -> [PROGRAM Ident ['(' IdentList ')'] ';']

ProgramBlock '.'

RelOp -> '>'

-> '<'

-> '<='

-> '>='

-> '<>'

-> IN

-> IS

-> AS

ExprList -> Expression/','...

文法的条目以黑体字开始,如面的Goal、Program和RelOp。

文法的每个条目至少有一个“->”连接符及跟随其后的文法内容。如上面的Goal和Program分别只有一个,而RelOp有多个。同一条目中多个“->”连接符之间是选择的“或”关系。

文法中的圆括号“(”和“)”之间的内容是必选项,但不含圆括号本身。如条目Goal中的“(Program | Package | Library | Unit)”,表示Object Pascal的目标(Goal)必须明确地给出。

文法中竖杠符号“|”连接的内容是可选择一个并且只能选择一个的“或”关系,但不含竖杠符号本身。如“Program | Package | Library | Unit”表示必须是其中之一。

文法中一对单引号“'”之间的内容通常是符号,表示该内容必须原样书写。如条目Program中的“'.'”和RelOp中的“'>'”。

文法中斜杠符号“/”之后的内容(当前行)是可选的,即可有可无,但不含斜杠符号本身。如条目ExprList中的“Expression/','...”。

此外,其它标识符要么是必须书写的保留字,要么是文法中给出进一步说明的条目。如PROGRAM是保留字,而Ident是文法条目。

因此,上面四个条目的详细含义依次解释如下。

Goal -> (Program | Package | Library | Unit)

含义:Object Pascal的目标的书写格式为程序、包、库、单元之一。(这四种目标分别又作为文法的条目进一步解释。实际上,编写Object Pascal源代码就是从此开始并到此结束。例如,Unit条目以句号保留字END和随后的“.”结束。)

Program -> [PROGRAM Ident ['(' IdentList ')'] ';']

ProgramBlock '.'

含义:程序(Object Pascal文法的四个目标之一)的书写格式为:

可选的程序首部、必须的程序块、必须的句号。

对于程序首部,如果要书写,则应书写为:必须的保留字PROGRAM、必须的作为程序名的标识符、可选的参数列表、必须的分号。

对于参数列表,如果要书写,则应书写为:必须的左圆括号、必须的标识符列表、必须的右圆括号。

因此,最简单的程序可以写成(程序块ProgramBlock中必须含有块Block,块Block中必须含有混合语句CompoundStmt,混合语句CompoundStmt中必须含有保留字BEGIN和保留字END):

begin

end.

典型的程序可以写成:

program MyTest;

uses MyUnit;

begin

...

end.

RelOp -> '>'

-> '<'

-> '<='

-> '>='

-> '<>'

-> IN

-> IS

-> AS

含义:关系运算符可以是符号 >、<、<=、>=、<> 之一或保留字IN、IS、AS之一。

ExprList -> Expression/','...

含义:表达式列表的书写规范是:一个表达式或多个表达式;如果是多个表达式,那么表达式之间必须以逗号“,”隔开。

>>更详细的请看:
Object Pascal Reference
>>下载地址:
http://www.efile.com.cn/?cjsh
http://www.efile.com.cn/eFile/cjsh/Object%20Pascal%20Reference.chm
 
收到,谢谢!研究中。。。
 
DLEPHI官方的语法里面有N多错误,自己修改。。。
 
定义有些混乱,关于类的定义本身就是错误的。估计DELPHI的编译器不可能是根据这个语法来写的。
 
后退
顶部