有一类问题,代码模板相同,但有少部分地方不同,一般可以写一个复杂的程序,使用不同的选项,完成不同的任务。或者,把公共的部分抽象成一个代码库,然后在不同程序中引用。但是,如果公共的部分很少,并且比较“专用”,或者因为其它原因,比较难以部署。怎么办?
实际上,有另一种完全不同的编程模式来实现:代码生成器。unix世界中最知名的代码生成器莫过于lex和yacc了。但是,不比每个代码生成器都那么复杂,比如这个代码生成器就非常简单,它只是简单地转换行记录:
#! /bin/sh
field_seperator="||"
output=b
while getopts :F:vo: arg
do
case $arg in
F ) field_seperator=$OPTARG;;
v ) ;;
o ) output=$OPTARG;;
: ) echo "$0: missing arg for -$OPTARG " >&2
exit;;
\?) echo "Invalid option -$OPTARG ignored." >&2
exit;;
esac
done
if [ $OPTIND -gt $# ]
then
# echo OPTIND=$OPTIND argc=$# >&2
echo "no program" >&2
exit
fi
program=${!#}
echo field_seperator=$field_seperator
cat > a.cpp <<+TemplateCFile
#include <vector>
#include <string.h>
#include <stdio.h>
const char field_seperator[]="||";
void split_row(char* line, std::vector<char*>& F, const char* fs)
{
char* col = line;
F.resize(0);
size_t fslen = strlen(fs);
if (fslen == 1) {
for (;;) {
F.push_back(col);
col = strchr(col, fs[0]);
if (col) {
col[0] = '\0';
col += 1;
} else
break;
}
}
else {
for (;;) {
F.push_back(col);
col = strstr(col, fs);
if (col) {
col[0] = '\0';
col += fslen;
} else
break;
}
}
}
int main(int argc, char* argv[])
{
size_t len1 = 0;
ssize_t len2;
char* line = NULL;
std::vector<char*> F;
while ((len2 = getline(&line, &len1, stdin)) != -1)
{
split_row(line, F, field_seperator);
int NF = F.size();
//--- begin user program
+TemplateCFile
echo $program >> a.cpp
cat >> a.cpp <<+TemplateCFile
//--- end user program
; // avoid user program missing ;
printf("\n");
}
if (line) free(line);
if (ferror(stdin)) {
perror("ferror(stdin)");
return 1;
}
return 0;
}
+TemplateCFile
sed -i 's/\(field_seperator\[\]=\).*";/\1"'$field_seperator'";/g' a.cpp
gcc -O2 a.cpp -lstdc++ -o $output
exit $?
可以象awk一样写程序:
# 相当于 awk -F, '{printf("%s\t%s\n", $1, $5)}'
# 使用 ',' 做列分隔符,输出第 1 和第 5 个字段,生成二进制可执行程序 myprog
./gencode.sh -F , -o myprog 'printf("%s\t%s\n", F[0], F[4])'
我当初写这个生成器的原因是发现非常简单的 awk 程序也比 C 慢 40 倍,以为这是本质上的性能差距,后来才发现不是
。
对这个简单的程序,使用awk更方便更安全,也不比C慢,但是一旦碰到其它类似问题而 awk 解决不了,这种模式就可以派上用场了。
分享到:
相关推荐
此外,可以使用自定义代码生成器添加有用的代码生成。 目前只有早期原型准备就绪。 尚不支持自定义生成器。 其中的一部分目前只是开发人员的路线图! 二进制下载 ##Available Features LSGL 支持代码生成,用于...
Python库是一组预先...例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。
它可以根据用户的输入生成自然语言响应,并可以进行微调以回答特定类型的问题,例如与特定领域或主题相关的问题。 此外,ChatGPT还可以用于创建文本生成工具。它可以根据输入数据生成类似人类的文本响应,并且具有很...
基于C语言的词法分析器的生成程序 基于C语言的词法分析器的生成程序是一个能够根据特定的词法规则生成词法分析器...此外,这个项目对于希望进入编译器设计、程序分析和代码生成等领域的人来说,是一个很好的实践机会。
简单的语法、词法、语义分析器 简单的语法、词法、语义分析器项目是一个编程项目,旨在构建一个能够对源代码进行...此外,这个项目对于希望进入编译器设计、程序分析和代码生成等领域的人来说,是一个很好的实践机会。
- **汇编器**:汇编语言源代码通过汇编器(assembler)转换成机器语言(机器码或二进制码),汇编器负责将助记符和符号地址解析为具体的机器指令和物理地址。 - **链接器**:生成的机器码通常需要链接器(linker)...
8.3.2 自定义代码的代码生成 8.3.3 元数据映射(对象关系(O/R)映射工具) 8.3.4 再次选择 8.4 分类 8.4.1 领域模型风格 8.4.2 映射工具风格 8.4.3 起点 8.4.4 API焦点 8.4.5 查询风格 8.4.6 高级数据库支持 8.4.7 ...
Lex词法分析器模拟器 Lex是一个由Douglas Crockford编写的词法分析器生成器,用于将正则表达式转换为C语言代码。...此外,这个项目对于希望进入编译器设计、程序分析和代码生成等领域的人来说,是一个很好的实践机会。
Java从网络取得文件 1个目标文件 简单 Java从压缩包中提取文件 1个目标文件 简单 Java存储与读取对象 1个目标文件 如题 Java调色板面板源代码 1个目标文件 摘要:Java源码,窗体界面,调色板 使用Java语言编写的一款...
Matlab(Matrix Laboratory)是一种专为数值计算和科学与工程应用而设计的高级编程语言和环境。在算法开发和实现方面,Matlab具有以下一些好处: 1. 丰富的数学和科学函数库:Matlab提供了广泛的数学、信号处理、...
python语言写的编译器,实现了词法分析和语法分析 编写一个完整的Python编译器,包括词法分析和语法分析,是一个...此外,这个项目对于希望进入编译器设计、程序分析和代码生成等领域的人来说,是一个很好的实践机会。
但是增加了一些小的限制和要求,这些限制和要求允许从单一来源构建很多本来必须手动创建的代码: 抽象句法树对象自动创建AST树的解析器(Nomic不是解析器生成器,而是为解析器生成器生成输入。因此,它可以利用现有...
C语言半自动词法分析器和半自动语法分析器 C语言的半自动词法分析器和半自动语法分析器是指那些部分手动编写、...此外,这个项目对于希望进入编译器设计、程序分析和代码生成等领域的人来说,是一个很好的实践机会。
Matlab(Matrix Laboratory)是一种专为数值计算和科学与工程应用而设计的高级编程语言和环境。在算法开发和实现方面,Matlab具有以下一些好处: 1. 丰富的数学和科学函数库:Matlab提供了广泛的数学、信号处理、...
Brancher是基于Symfony组件并使用Twig模板语言的通用静态站点生成器。 它被设计为易于使用,但可扩展并且可用于任何类型的站点结构。 执照 Brancher是免费软件; 您可以根据自由软件基金会发布的GNU通用公共许可的...
词法分析器 带有展示界面的词法分析器 带有展示界面的词法分析器是一个能够将源代码字符串转换为词法单元序列,并...此外,这个项目对于希望进入编译器设计、程序分析和代码生成等领域的人来说,是一个很好的实践机会。
Matlab(Matrix Laboratory)是一种专为数值计算和科学与工程应用而设计的高级编程语言和环境。在算法开发和实现方面,Matlab具有以下一些好处: 1. 丰富的数学和科学函数库:Matlab提供了广泛的数学、信号处理、...
特性在工作区的任意位置创建各种类型项目的文件(如Java、Python、JavaScript等),文件内容基于模板和用户输入生成模板配置完全基于配置文件,欢迎大家pull request,添加自己领域内的通用模板完全键盘操作自定义...
目标:创建一个能够识别和处理C语言源代码中所有词法元素的程序。 主要任务: 字符流处理:读取源代码文件,并处理其中的字符流,包括忽略空白、换行符和注释。 词法单元识别:根据预定义的语言规则,将字符流分割...