Coco/R 更Cool些,Coco/R 使用增强的 EBNF 文法建立递归下降分析的分析器(Recursive Descent Parser)和扫描器(Scanner)。Coco/R 除了提供调用分析器的主程序模块之外,还提供语义(semantic )模块在文法之中调用(如,符号表处理和代码生成器),可以直接在grammer 内写语意动作【用你自己喜欢的语言。俺是中意Delphi】。
Coco/R (Cocol/R) 的输入语言基于属性文法, 属性文法是由Knuth 作为一种上下文无关的形式化语义语言引入的。
最初编译器完成的分析是静态语义分析如(C语言)。它们描述没有给定顺序的符号属性之间的依赖性, 它们包括构造符号表、记录声明中建立的名字的含义、在表达式和语句中进行类型推断和类型检查以及在语言的类型规则作用域内判断它们的正确性。当时的许多编译器都使用这样的静态语义分析。
Coco/R 是对Coco [ReM?89]版本的增强。它们之间的主要不同在于Coco/R 使用了递归下降分析代替表驱动方式的分析。Coco/R 集成扫描器和分析器描述,避免了在创建的部分之间接口的问题。
接下来的例子会使大家对编译器说明有一个初步的印象。对编译器说明更准确的描述说明请见第二部分。本例将说明如何翻译变量声明。一个以上下文无关的EBNF范式文法开始的变量声明描述如下:
VarDeclaration = Ident {"," Ident} ":" Type ";".
只要简单写下该规则,一个依照句法检查变量声明的分析器就已经获得了。为了处理语义,最好还是必须考虑怎样翻译变量声明。这需要考虑一下的事项:
VarDeclaration(变量声明), Ident(标示符) 和 Type (类型)的语义是什么? 换句话说,识别的符号产生的什么? 为了能够识别它们必须提供什么样的内容信息?这导致了所谓的符号属性的出现。标示符的属性是它的名称,而类型的属性是一些类型信息的节点(Node)。 变量声明( VarDeclaration )并没有产生有关它们属性的信息。 恰恰相反,它需要一个来自上下文的属性;如,它需要知道地址空间中变量的下一个空闲地址值。属性可以被当作语法符号的(输入和输出)参数。它们被表示如下:
Ident <name>
Type <typ>
VarDeclaration <adr>
下一个问题是: 翻译这样的结构(VarDeclaration)需要什么样的动作? 这些动作在通用编程语言(如: Oberon [Wirth89])中被用公式表示。 这些动作被扩在符号 "(." 和 ".)" 之间。 一个语义动作通常在产生式(Production)的右边,并在分析到该符号的时候被执行。这些考虑导致了基于属性的产生式[使用Pascal语言表示的语意]:
VarDeclaration <VAR adr: LONGINT>
(. VAR obj, obj1: SymTab.Object; typ: SymTab.Type; n, a: LONGINT;
name: ARRAY 32 OF CHAR;.)
= Ident <name> (. obj := SymTab.Find(name); obj.link := NIL; n := 1 .)
{ "," Ident <name> (. obj1 := SymTab.Find(name); obj1.link := obj; obj := obj1; INC(n) .)
} ":"
Type <typ> (. adr := adr + n* typ.size; a := adr;
WHILE obj # NIL DO DEC(a, typ.size); obj.adr := a; obj := obj.link END .)
";".
属性文法可以作为特别的编译器构建语言(类似于程序)来阅读。
例子,
表达式一般文法产生式(把属性和语义动作去掉了的):
Expr = Expression "=" .
Expression = Term { '+' Term | '-' Term } .
Term = Factor { '*' Factor | '/' Factor } .
Factor = real | '(' Expression ')' .
表达式的属性文法产生式:
Expr = (. Init ; .) Expression < fResult > "="(. Final ; .) .
Expression <VAR e: Double>
(. VAR t: Double ; .)
=
Term <e>
{ '+' Term < t > (. e := e + t .)
| '-' Term < t > (. e := e - t .)
} .
Term <VAR t: Double>
(. VAR f: Double ; .)
=
Factor < t >
{ '*' Factor < f > (. t := t * f .)
| '/' Factor < f > (. t := t / f .)
} .
Factor <VAR f: Double>
=
real (. GetNumber(f) .)
| '(' Expression < f > ')' .
网站: http://www.tetzel.com/CocoR/
实现了Delphi版本和C#的CocoR.
Coco/R (Cocol/R) 的输入语言基于属性文法, 属性文法是由Knuth 作为一种上下文无关的形式化语义语言引入的。
最初编译器完成的分析是静态语义分析如(C语言)。它们描述没有给定顺序的符号属性之间的依赖性, 它们包括构造符号表、记录声明中建立的名字的含义、在表达式和语句中进行类型推断和类型检查以及在语言的类型规则作用域内判断它们的正确性。当时的许多编译器都使用这样的静态语义分析。
Coco/R 是对Coco [ReM?89]版本的增强。它们之间的主要不同在于Coco/R 使用了递归下降分析代替表驱动方式的分析。Coco/R 集成扫描器和分析器描述,避免了在创建的部分之间接口的问题。
接下来的例子会使大家对编译器说明有一个初步的印象。对编译器说明更准确的描述说明请见第二部分。本例将说明如何翻译变量声明。一个以上下文无关的EBNF范式文法开始的变量声明描述如下:
VarDeclaration = Ident {"," Ident} ":" Type ";".
只要简单写下该规则,一个依照句法检查变量声明的分析器就已经获得了。为了处理语义,最好还是必须考虑怎样翻译变量声明。这需要考虑一下的事项:
VarDeclaration(变量声明), Ident(标示符) 和 Type (类型)的语义是什么? 换句话说,识别的符号产生的什么? 为了能够识别它们必须提供什么样的内容信息?这导致了所谓的符号属性的出现。标示符的属性是它的名称,而类型的属性是一些类型信息的节点(Node)。 变量声明( VarDeclaration )并没有产生有关它们属性的信息。 恰恰相反,它需要一个来自上下文的属性;如,它需要知道地址空间中变量的下一个空闲地址值。属性可以被当作语法符号的(输入和输出)参数。它们被表示如下:
Ident <name>
Type <typ>
VarDeclaration <adr>
下一个问题是: 翻译这样的结构(VarDeclaration)需要什么样的动作? 这些动作在通用编程语言(如: Oberon [Wirth89])中被用公式表示。 这些动作被扩在符号 "(." 和 ".)" 之间。 一个语义动作通常在产生式(Production)的右边,并在分析到该符号的时候被执行。这些考虑导致了基于属性的产生式[使用Pascal语言表示的语意]:
VarDeclaration <VAR adr: LONGINT>
(. VAR obj, obj1: SymTab.Object; typ: SymTab.Type; n, a: LONGINT;
name: ARRAY 32 OF CHAR;.)
= Ident <name> (. obj := SymTab.Find(name); obj.link := NIL; n := 1 .)
{ "," Ident <name> (. obj1 := SymTab.Find(name); obj1.link := obj; obj := obj1; INC(n) .)
} ":"
Type <typ> (. adr := adr + n* typ.size; a := adr;
WHILE obj # NIL DO DEC(a, typ.size); obj.adr := a; obj := obj.link END .)
";".
属性文法可以作为特别的编译器构建语言(类似于程序)来阅读。
例子,
表达式一般文法产生式(把属性和语义动作去掉了的):
Expr = Expression "=" .
Expression = Term { '+' Term | '-' Term } .
Term = Factor { '*' Factor | '/' Factor } .
Factor = real | '(' Expression ')' .
表达式的属性文法产生式:
Expr = (. Init ; .) Expression < fResult > "="(. Final ; .) .
Expression <VAR e: Double>
(. VAR t: Double ; .)
=
Term <e>
{ '+' Term < t > (. e := e + t .)
| '-' Term < t > (. e := e - t .)
} .
Term <VAR t: Double>
(. VAR f: Double ; .)
=
Factor < t >
{ '*' Factor < f > (. t := t * f .)
| '/' Factor < f > (. t := t / f .)
} .
Factor <VAR f: Double>
=
real (. GetNumber(f) .)
| '(' Expression < f > ')' .
网站: http://www.tetzel.com/CocoR/
实现了Delphi版本和C#的CocoR.