繁体   English   中英

运行GCC预处理器非C文件

[英]Run GCC preprocessor non-C files

我正在使用专有的开发环境来编译用C编写的代码以及IEC 61131语言。 对于C编译,它使用GCC 4.1.2和这些构建选项:

-fPIC -O0 -g -nostartfiles -Wall -trigraphs -fno-asm

编译是由使用Cygwin在Windows上运行的程序完成的。

我的问题是,IEC语言预处理器没那么有用(根本不支持#define),我想使用宏! 我不明白为什么GCC预处理器真正关心它正在处理什么语言(我的目标语言是结构化文本),所以我想看看是否有人知道如何让它来处理不同文件类型的文件然后不进一步编译(我只是在文件通过IEC编译器运行之前寻找宏扩展)。 我对编译器选项和环境一无所知,因为我从来没有处理它们,我只是编写C代码并且它神奇地编译并传输到我的目标系统来运行。

我唯一能做的就是添加构建选项并在执行任何操作之前执行批处理文件。 我认为我最大的希望在于使用批处理文件来处理某个扩展名的所有文件,但我甚至不知道gnuinst文件夹中要使用哪些可执行文件,更不用说用于运行文件的标志。

几乎任何C预处理器,包括gcc的cpp ,都会假设它的输入是有效的C代码。 它必须按照C(或C ++或Objective-C)规则对输入进行标记,因为它必须将其输入解析为标记(更准确地说是预处理标记)。 在令牌级别之上的构造不应该是一个问题。

您当然可以使用cppgcc -E来预处理非C源代码的文本,但某些输入结构会导致问题。

以评论为例:

$ cat foo.txt
#define ADDTHEM(x, y) ((x) + (y))
ADDTHEM(2, 3)
$ gcc -E - < foo.txt
# 1 "<stdin>"
# 1 "<command-line>"
# 1 "<stdin>"

((2) + (3))

请注意,我必须使用gcc -E - < foo.txt而不是gcc -E foo.txt ,因为默认情况下gcc会将.txt文件视为链接器输入文件。

但是,如果向foo.txt中添加一些不包含有效C预处理程序令牌的内容,则可能会出现问题:

$ cat foo.txt 
#define ADDTHEM(x, y) ((x) + (y))
ADDTHEM(2, 3)
ADDTHEM('c, "s)
$ gcc -E - < foo.txt
# 1 "<stdin>"
# 1 "<command-line>"
# 1 "<stdin>"

((2) + (3))
<stdin>:3:9: warning: missing terminating ' character [enabled by default]
<stdin>:3:0: error: unterminated argument list invoking macro "ADDTHEM"
ADDTHEM

(尝试将Ada源代码提供给C预处理器遇到了这种问题,因为Ada使用了孤立的撇号'字符作为其属性语法。)

因此, 如果输入语言不使用无效的C预处理程序标记,则可以执行此操作。

有关预处理令牌的更多信息,请参阅C标准的N1570草案 ,第6.4节。

在我检查GNU cpp手册之前,我实际上已经写了上述内容,其中说:

C预处理器仅用于C,C ++和Objective-C源代码。 在过去,它被滥用为一般的文本处理器。 它会阻塞不遵守C的词汇规则的输入。 例如,撇号将被解释为字符常量的开头,并导致错误。 此外,您不能依赖它来保留对C系列语言不重要的输入特性。 如果预处理了Makefile,则将删除所有硬选项卡,并且Makefile将不起作用。

话虽如此,你可以经常在不使用C的东西上使用cpp。其他Algol-ish编程语言通常是安全的(Pascal,Ada等)。所以是汇编,谨慎。 `-traditional-cpp'模式保留更多的空白区域,否则更宽松。 通过编写C或C ++样式注释而不是本地语言注释,并保持宏简单,可以避免许多问题。

只要有可能,您应该使用适合您所编写语言的预处理器。现代版本的GNU汇编程序具有宏功能。 大多数高级编程语言都有自己的条件编译和包含机制。 如果所有其他方法都失败了,请尝试使用真正的通用文本处理器,例如GNU M4。

(该手册的作者显然错过了Ada属性语法的问题。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM