如何在C#和Visual Studio中使用COCO/R

编译器的创建是一个复杂的过程,但有了COCO/R这样的工具,可以简化很多步骤。本文不是讨论COCO/R的好处,也不是讲解如何编写编译器,而是介绍如何将其设置为与C#Visual Studio一起使用。

Visual Studio的定制挑战

Visual Studio是一个功能强大的开发环境,但它并不是一个容易定制的工具,尤其是对于非标准语言的支持。虽然C#、VB.NET等语言已经得到支持,F#也可以通过额外的安装包添加(仅限旧版本的Visual Studio,VS2010及以后版本已内置F#支持),但要读取和编译非标准语言则相对困难。

集成COCO/R的方法

本文的目标是展示如何将COCO/R作为一个工具与Visual Studio集成使用。

COCO/R可以从其官方网站下载。为了使COCO/R工作,需要下载以下文件:

  • Coco.exe - 这个可执行文件读取模板文件并生成类文件,构成基本的编译器(或文件阅读器、计算器等)。
  • Scanner.frame - 这是用于生成Scanner的模板文件。
  • Parser.frame - 这是用于生成Parser的模板文件。

此外,下载一个COCO的输入模板文件也很有用。虽然COCO/R的主页上提供了一些示例,但这些文件适用于复杂的语法,对于从头开始创建语法并不理想。一个好的模板可以在以下网址找到:

在这个模板中,Empty.atg提供了一个带有注释的坚实模板,说明了每个特性是什么。为了设置,只需要对这个文件进行最小的工作。在文件的"Productions"部分,可以找到以下行:

Empty =

这应该被更改为:

Empty = "a"

这确保了产生规则不为空,因此在运行COCO/R时,应该不会有错误。至于文件的实际细节,这里不会详细解释,因为这不是严格必需的设置过程——这是构建过程中唯一需要更改的地方。

现在所有文件都下载到一个文件夹并设置好了,可以运行COCO/R来生成一个基本的编译器。从命令行运行程序:

coco Empty.atg -namespace "MyNamespace"

这里使用"Empty.atg"作为coco的输入文件,并指定要使用的命名空间是"MyNamespace"。

第一次运行时,目标目录中会生成两个文件:

  • Parser.cs - 构成基本编译器的Parser文件。
  • Scanner.cs - 构成基本编译器的Scanner文件。

第二次运行命令时,COCO/R会创建备份——现有的Scanner和Parser文件会在扩展名上加上"old",以便程序员在需要时可以回退到旧版本。同时也会创建新的Parser和Scanner。因此,在第二次运行后,目标文件夹中总是有4个生成的文件。每次运行COCO/R时,"old"文件都会被覆盖。

输出文件为程序员节省了很多工作,但个人对输出文件有一些问题:

  • 类没有标记为"partial"——在VS编辑器中对文件所做的任何更改都会在每次使用COCO/R时丢失。如果将文件标记为partial,那么可以在单独的文件中添加额外的方法,这些文件不会被COCO/R覆盖。
  • 输出文件总是有相同的名称,不管编译器的名称是什么。如果要创建多遍编译器或支持多种语言,就需要创建多个Parser和Scanner文件,并且有不同的文件名,以免相互覆盖。

发现的解决方案是将ATG文件和输出文件放在不同的目录和命名空间中。

由于编译命令输入繁琐,并且可能使用多个目标,发现设置一个批处理文件来重建类很有帮助。首先,设置目录结构如下:

  • (root) - Coco.exe, Parser.Frame, Scanner.Frame, Build.bat
  • (root)\FirstPass - Empty.atg(包含第一次编译器通过的规范)
  • (root)\SecondPass - Empty.atg(包含第二次编译器通过的规范)

以下是批处理文件的内容,用于编译两次通过的编译器:

coco "Pass1\Empty.atg" -namespace "Pass1" -frames "" -o "Pass1" coco "Pass2\Empty.atg" -namespace "Pass2" -frames "" -o "Pass2"

这里在两个目录中编译Empty.atg文件,给它们不同的命名空间。指定要使用的框架文件与coco.exe在同一个目录中,并且使用空字符串,并且用“-o”指定根目录下的输出目录。假设ATG是有效的COCO输入,文件夹现在应该如下结构:

  • (root) - Coco.exe, Parser.Frame, Scanner.Frame, Build.bat
  • (root)\FirstPass - Empty.atg, Scanner.cs, Parser.cs, Scanner.cs.old(如果不是第一次运行), Parser.cs.old(如果不是第一次运行)
  • (root)\SecondPass - Empty.atg, Scanner.cs, Parser.cs, Scanner.cs.old(如果不是第一次运行), Parser.cs.old(如果不是第一次运行)

当然,如果COCO/R有错误信息,批处理文件需要从命令行运行,以便读取错误信息。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485