代码生成方案——parser && generaotr带来的无限想象

2,036 阅读3分钟

什么是代码生成

在编译原理中,有“目标代码生成”这个步骤,指的是把语法分析后或者优化后的中间代码变换成目标代码。本文谈及的代码生成是指以配置文件等方式注入代码模板,生成同质化的代码。

举例而言,在某些node项目框架中,可以使用命令行指定名称动态生成controllerservice等模板文件,又或者以proto定义文件生成grpc框架的初始文件。都是本文谈及的代码生成。

技术方案

下面以笔者编写的jce2proto小工具为例,分享一个可行的代码生成技术方案。

项目背景

中心部分项目在由tafgo迁移trpc,而其中有些后台服务字段很多,jce文件多达上千行。如果手工改写proto文件,难免费时费力,而jce和proto同为rpc定义文件,其主要结构都是strcut、field、service等类似的概念,理论上可以借由程序自动转换。

技术选型

上面说到的这个具体问题可以分为两个主要步骤——parser部分(jce文件解析为结构化数据)和generator部分(结构化数据按照模板生成proto)。

Parser

parser部分的可选技术方案有:原始的正则;LexFlexBison等主流的语法解析器。笔者选用的是node中的一个类似Bison等工具的解析包Peg.js,其主要优势是相比Bison等更贴近JS且写法更简单。

其全称为Parser Generator for JavaScript,顾名思义,是用来生成语法解析JS文件的一个工具,文档描述相当简单,官网还贴心地给出了一个online工具,可以左边写parser定义,右边即时校验。

语法部分以截图为例,主要是三方面:

  • token:首行,一般驼峰式写法
  • rule: 类正则写法,支持右递归
  • output:{}包裹的返回值,如果得到的数组,可以使用text()方法转为文字

Generator

generator部分的可选技术方案有:手工拼接代码;各类模板引擎。笔者选用的是一个常见的前端模板引擎handlebarsjs,相比手动拼接代码,模板引擎的代码量更少,可读性和维护难度都不错。唯一的劣势是模板引擎的灵活性不足,笔者选用的handlebarsjs对js的支持并不好,没法在if、for等处使用全部js写法,只得在node中先对jce解析出来的数据进行一次转换。

更多想象

笔者近期工作都是写管理端前后台,这类工作重复度高,每个实体都要增、删、改、查,但又不可完全抽离成公共函数,因为每个实体都有自己的特殊逻辑(当然并非不能抽,但设计时考虑极多,需要随业务进行足够灵活的修改)。私以为对于这类工作,借助装饰器、数据流及代码生成,或许可以极大解放生产力。当然其对于设计模式和编程思想的要求都甚高,希望笔者在日后工作实践中不断提炼各类常用能力,深入探究工程化方案,找到更好的出路。