在没有被要求的情况下进行呼叫 bison -y
我正在编写一个语法,名为 portugol
。文件名很基本,但我选择将我的 C 程序命名为 portugol.c
。
所以,基本上,我必须这样做:(
flex portugol.l ==> lex.yy.c
bison -dy portugol.y ==> y.tab.c and y.tab.h
gcc y.tab.c lex.yy.c portugol.c -o portugol.bin -lm -ly ==> portugol.bin
我也有 portugol.h,但它与问题无关)
很长一段时间以来,我使用一个名为 flexyagcc.sh
的 shell 脚本做这个。过程中没有错误。
所以现在我决定学习makefile
。
我面临的问题是,由于某种奇怪的原因,我调用的“bison -dy
”后面跟着我没有写的命令:mv -f y.tab.c portugol .c
好吧,这破坏了我手工制作的源文件!
我已经尽了一切努力,但无法摆脱这个“mv
”。
我什至睡了一会儿并尝试:
y.tab.c y.tab.h : portugol.y
@echo --- bison -----------------------------------------------
mv -f portugol.c ptg.c
$(BISON) $(BFLAGS) portugol.y
@echo --- bison sleeping --------------------------------------
sleep 5
-mv -f portugol.c y.tab.c
-mv -f ptg.c portugol.c
但令我惊讶的是,我收到了以下事件(按此顺序):
$ make all o=pequeno
--- bison -----------------------------------------------
mv -f portugol.c ptg.c
bison -dy portugol.y
--- bison sleeping --------------------------------------
sleep 5
mv -f portugol.c y.tab.c
mv: cannot stat `portugol.c': No such file or directory
make: [y.tab.c] Error 1 (ignored)
mv -f ptg.c portugol.c
bison -dy portugol.y
mv -f y.tab.c portugol.c
惊喜! mv
命令是最后一个!不管我做什么。我创建了其他规则,只是为了让它最后发生(或者首先欺骗递归过程)。决不!我还使用了指令: .NOTPARALLEL.
没办法。
我还尝试在同一行中执行所有操作,以确保它们按给定的顺序执行:
mv -f portugol.c ptg.c && $(BISON) $(BFLAGS) portugol.y && sleep 5 && mv -f portugol.c y.tab.c && mv -f ptg.c portugol.c
没有成功。
好吧,在我放弃之前,我决定使用标准的 bison 输出。所以,我会:
flex portugol.l ==> lex.yy.c
bison -d portugol.y ==> portugol.tab.c and y.tab.h
gcc portugol.tab.c lex.yy.c portugol.c -o portugol.bin -lm -ly ==> portugol.bin
但我仍然得到这个:
--- bison -----------------------------------------------
bison -d portugol.y
bison -y portugol.y
mv -f y.tab.c portugol.c
我还尝试在野牛之前和之后尝试 chmod -w
和 +w
,没门。
现在,我已经没有想法了。
有没有办法阻止 make 调用第二个野牛?或者调用mv
命令?或者欺骗它不覆盖我的文件 portugol.c
?
谢谢! Beco
PS-编辑。使用:
Ubuntu 10.04.2 LTS
GNU Make 3.81
PPS。已编辑。小错别字。
购买力平价。已编辑。回答 伊势紫藤:
谢谢您的回答。我已将您的 makefile 保存为 makefile2 并尝试过。我从make得到的答案是:
$ make -f makefile2
bison -dy portugol.y
yacc portugol.y
mv -f y.tab.c portugol.c
gcc y.tab.c lex.yy.c portugol.c -o portugol.bin -lm -ly
gcc: y.tab.c: No such file or directory
make: *** [portugol.bin] Error 1
我还注意到“今天”第二个bison调用不是bison调用,而是yacc调用。也许我们在这里谈论一些环境变量?它也随着我的 makefile 的变化而变化:
$ make all o=pequeno
--- bison -----------------------------------------------
bison --defines=y.tab.h --output=y.tab.c portugol.y
--- flex ------------------------------------------------
flex portugol.l
yacc portugol.y
mv -f y.tab.c portugol.c
PPPPS。回答贝塔。你的建议有效。我调用了 make y.tab.c 并得到了一个简单的:
$ make y.tab.c
--- bison -----------------------------------------------
bison --defines=y.tab.h --output=y.tab.c portugol.y
$
这是我完整的 makefile:
# Compila o compilador Portugol usando lex e yacc,
# e opcionalmente gera o .asm.c e o .bin
# a partir do fonte .ptg usando o novo compilador gerado.
#
#/*
# arquivo: makefile
# Autor: Ruben Carlo Benante
# Email: ***@beco.cc
# Data: 23/04/2009
# Modificado: 22/03/2011
# Versao: Portugol v3q
#*/
#
# Exemplo:
# ./flexyagcc portugol teste
#
# inicia os seguintes processos:
# flex portugol.l (gera lex.yy.c)
# bison -dy portugol.y (gera yy.tab.c e yy.tab.h)
# gcc y.tab.c lex.yy.c portugol.c -o portugol.bin -lm -ly (gera portugol.bin)
#
# inicia opcionalmente (ultimas linhas descomentadas):
# portugol.bin teste.ptg teste.asm.c (gera teste.asm.c)
# gcc -x c teste.asm.c -o teste.bin -lm (gera teste.bin)
#
#
# entrada:
# portugol.l (arquivo em linguagem lex, analisador lexico)
# portugol.y (arquivo em linguagem yacc, analisador sintatico)
# portugol.c (arquivo em linguagem c, gerador de codigo)
# entrada opcional:
# teste.ptg (arquivo em linguagem portugol)
#
# saida:
# lex.yy.c (saida do lex, em linguagem c)
# y.tab.c (saida do yacc, em linguagem c)
# y.tab.h (saida do yacc, definicoes da linguagem portugol)
# portugol.bin (saida do gcc, arquivo executavel, finalmente o compilador portugol)
# saida opcional:
# teste.asm.c (saida do compilador portugol, arquivo em codigo de quadruplas)
# teste.bin (saida do gcc, arquivo executavel, o fonte .ptg em binario)
#
######################################
LEX = flex
BISON = bison
BFLAGS = --defines=y.tab.h --output=y.tab.c
CC = gcc
#CFLAGS = -g0 -O3 -Wall
CFLAGS = -g0
OBJS = y.tab.o lex.yy.o portugol.o
#OBJS = portugol.tab.o lex.yy.o portugol.o
DEPS = portugol.h y.tab.h
SOURCES = y.tab.c lex.yy.c portugol.c
#SOURCES = portugol.tab.c lex.yy.c portugol.c
.PHONY : clean cleanall cleanptg run all makebug teste
.NOTPARALLEL :
#portugol.bin : lex.yy.c y.tab.c y.tab.h portugol.c portugol.h
portugol.bin : $(SOURCES) $(DEPS) $(OBJS)
@echo --- gcc portugol ----------------------------------------
$(CC) $(CFLAGS) $(OBJS) -o portugol.bin -lm -ly
# gcc lex.yy.c y.tab.c portugol.c -o portugol.bin -lm -ly
# $(CC) $(CFLAGS) $(SOURCES) -o portugol.bin -lm -ly
%.o : %.c
@echo --- gcc objects -----------------------------------------
$(CC) $(CFLAGS) -c $< -o $@
#portugol.tab.c y.tab.h : portugol.y
y.tab.c y.tab.h : portugol.y
@echo --- bison -----------------------------------------------
$(BISON) $(BFLAGS) portugol.y
# @echo --- bison y.tab.c ---------------------------------------
# mv -f portugol.c ptg.c
# sleep 3
# -mv -f portugol.c y.tab.c
# -mv -f ptg.c portugol.c
lex.yy.c : portugol.l
@echo --- flex ------------------------------------------------
$(LEX) $(LFLAGS) portugol.l
teste :
@echo --- testing ---------------------------------------------
@echo $(o)
#Portugol -----------
%.asm.c : %.ptg portugol.bin
@echo --- portugol --------------------------------------------
./portugol.bin $< $@
%.bin : %.asm.c
@echo --- gcc asm ---------------------------------------------
$(CC) -x c $< -o $@ -lm
run : $(o).bin
@echo --- running! --------------------------------------------
./$(o).bin
all : $(o).bin
clean:
-rm lex.yy.c y.tab.c y.tab.h *.o portugol.bin portugol.tab.c
cleanall:
-rm lex.yy.c y.tab.c y.tab.h *.o *.bin
cleanasm:
-rm *.asm.c
VPS。重要编辑更新。注意真正问题的可能指示:
我将名称 portugol.y
更改为 portugol.syn
并且问题已经停止!
--- bison -----------------------------------------------
bison --defines=y.tab.h --output=y.tab.c portugol.syn
---------------------------------------------------------
怎么样?在我看来,这表明 make 对文件“.y”有一些默认评估,现在我们需要回答这个问题,找出其根源,以及如何禁用它。非常感谢。
I have a grammar I'm writing, called portugol
. The files names are basic, but I chose to call my c program portugol.c
.
So, basically, I have to do:
flex portugol.l ==> lex.yy.c
bison -dy portugol.y ==> y.tab.c and y.tab.h
gcc y.tab.c lex.yy.c portugol.c -o portugol.bin -lm -ly ==> portugol.bin
(I also have portugol.h, but it is irrelevant to the problem)
For long time now, I'm using a shell script I called flexyagcc.sh
that do this. No error in the process.
So now I decided to learn makefile
.
The problem I'm facing is that for some odd reason, "bison -dy
" I called is followed by this command I didn't write: mv -f y.tab.c portugol.c
Well, this destroys my handmade source file!
I've tried all I could, but could not get rid of this "mv
".
I even did a sleep
and tried:
y.tab.c y.tab.h : portugol.y
@echo --- bison -----------------------------------------------
mv -f portugol.c ptg.c
$(BISON) $(BFLAGS) portugol.y
@echo --- bison sleeping --------------------------------------
sleep 5
-mv -f portugol.c y.tab.c
-mv -f ptg.c portugol.c
But for my surprise, I got the following events (in this order):
$ make all o=pequeno
--- bison -----------------------------------------------
mv -f portugol.c ptg.c
bison -dy portugol.y
--- bison sleeping --------------------------------------
sleep 5
mv -f portugol.c y.tab.c
mv: cannot stat `portugol.c': No such file or directory
make: [y.tab.c] Error 1 (ignored)
mv -f ptg.c portugol.c
bison -dy portugol.y
mv -f y.tab.c portugol.c
Surprise! The mv
command is the last one! No matter what I do. I created other rules, just to make it happen last (or first to trick the recursive process). No way! I also used the directive: .NOTPARALLEL.
No way.
I also tried all in the same line, to be sure they execute in the given order:
mv -f portugol.c ptg.c && $(BISON) $(BFLAGS) portugol.y && sleep 5 && mv -f portugol.c y.tab.c && mv -f ptg.c portugol.c
No success.
Well, before I gave up, I decided to use the standard bison output. So, I would have:
flex portugol.l ==> lex.yy.c
bison -d portugol.y ==> portugol.tab.c and y.tab.h
gcc portugol.tab.c lex.yy.c portugol.c -o portugol.bin -lm -ly ==> portugol.bin
But I still get this:
--- bison -----------------------------------------------
bison -d portugol.y
bison -y portugol.y
mv -f y.tab.c portugol.c
I also tried to chmod -w
before and +w
after bison, no way.
For now, I run out of ideas.
Is there a way to prevent make to call the second bison? Or to call the mv
command? Or to trick it to not overwrite my file portugol.c
?
Thanks!
Beco
PS- Edited. Using:
Ubuntu 10.04.2 LTS
GNU Make 3.81
PPS. Edited. Minor typos.
PPPS. Edited. Answering Ise wisteria:
Thanks for your answer. I've saved your makefile as makefile2 and tried. The answer I got from the make is:
$ make -f makefile2
bison -dy portugol.y
yacc portugol.y
mv -f y.tab.c portugol.c
gcc y.tab.c lex.yy.c portugol.c -o portugol.bin -lm -ly
gcc: y.tab.c: No such file or directory
make: *** [portugol.bin] Error 1
I also noted that "today" the second bison call is not a bison call, but a yacc call. Maybe we are talking about some environment variable here? It also changes with my makefile:
$ make all o=pequeno
--- bison -----------------------------------------------
bison --defines=y.tab.h --output=y.tab.c portugol.y
--- flex ------------------------------------------------
flex portugol.l
yacc portugol.y
mv -f y.tab.c portugol.c
PPPPS. Answering Beta. Your advice works. I called make y.tab.c and got a simple:
$ make y.tab.c
--- bison -----------------------------------------------
bison --defines=y.tab.h --output=y.tab.c portugol.y
$
Here is my complete makefile:
# Compila o compilador Portugol usando lex e yacc,
# e opcionalmente gera o .asm.c e o .bin
# a partir do fonte .ptg usando o novo compilador gerado.
#
#/*
# arquivo: makefile
# Autor: Ruben Carlo Benante
# Email: ***@beco.cc
# Data: 23/04/2009
# Modificado: 22/03/2011
# Versao: Portugol v3q
#*/
#
# Exemplo:
# ./flexyagcc portugol teste
#
# inicia os seguintes processos:
# flex portugol.l (gera lex.yy.c)
# bison -dy portugol.y (gera yy.tab.c e yy.tab.h)
# gcc y.tab.c lex.yy.c portugol.c -o portugol.bin -lm -ly (gera portugol.bin)
#
# inicia opcionalmente (ultimas linhas descomentadas):
# portugol.bin teste.ptg teste.asm.c (gera teste.asm.c)
# gcc -x c teste.asm.c -o teste.bin -lm (gera teste.bin)
#
#
# entrada:
# portugol.l (arquivo em linguagem lex, analisador lexico)
# portugol.y (arquivo em linguagem yacc, analisador sintatico)
# portugol.c (arquivo em linguagem c, gerador de codigo)
# entrada opcional:
# teste.ptg (arquivo em linguagem portugol)
#
# saida:
# lex.yy.c (saida do lex, em linguagem c)
# y.tab.c (saida do yacc, em linguagem c)
# y.tab.h (saida do yacc, definicoes da linguagem portugol)
# portugol.bin (saida do gcc, arquivo executavel, finalmente o compilador portugol)
# saida opcional:
# teste.asm.c (saida do compilador portugol, arquivo em codigo de quadruplas)
# teste.bin (saida do gcc, arquivo executavel, o fonte .ptg em binario)
#
######################################
LEX = flex
BISON = bison
BFLAGS = --defines=y.tab.h --output=y.tab.c
CC = gcc
#CFLAGS = -g0 -O3 -Wall
CFLAGS = -g0
OBJS = y.tab.o lex.yy.o portugol.o
#OBJS = portugol.tab.o lex.yy.o portugol.o
DEPS = portugol.h y.tab.h
SOURCES = y.tab.c lex.yy.c portugol.c
#SOURCES = portugol.tab.c lex.yy.c portugol.c
.PHONY : clean cleanall cleanptg run all makebug teste
.NOTPARALLEL :
#portugol.bin : lex.yy.c y.tab.c y.tab.h portugol.c portugol.h
portugol.bin : $(SOURCES) $(DEPS) $(OBJS)
@echo --- gcc portugol ----------------------------------------
$(CC) $(CFLAGS) $(OBJS) -o portugol.bin -lm -ly
# gcc lex.yy.c y.tab.c portugol.c -o portugol.bin -lm -ly
# $(CC) $(CFLAGS) $(SOURCES) -o portugol.bin -lm -ly
%.o : %.c
@echo --- gcc objects -----------------------------------------
$(CC) $(CFLAGS) -c lt; -o $@
#portugol.tab.c y.tab.h : portugol.y
y.tab.c y.tab.h : portugol.y
@echo --- bison -----------------------------------------------
$(BISON) $(BFLAGS) portugol.y
# @echo --- bison y.tab.c ---------------------------------------
# mv -f portugol.c ptg.c
# sleep 3
# -mv -f portugol.c y.tab.c
# -mv -f ptg.c portugol.c
lex.yy.c : portugol.l
@echo --- flex ------------------------------------------------
$(LEX) $(LFLAGS) portugol.l
teste :
@echo --- testing ---------------------------------------------
@echo $(o)
#Portugol -----------
%.asm.c : %.ptg portugol.bin
@echo --- portugol --------------------------------------------
./portugol.bin lt; $@
%.bin : %.asm.c
@echo --- gcc asm ---------------------------------------------
$(CC) -x c lt; -o $@ -lm
run : $(o).bin
@echo --- running! --------------------------------------------
./$(o).bin
all : $(o).bin
clean:
-rm lex.yy.c y.tab.c y.tab.h *.o portugol.bin portugol.tab.c
cleanall:
-rm lex.yy.c y.tab.c y.tab.h *.o *.bin
cleanasm:
-rm *.asm.c
VPS. Important edit update. Attention for a possible indication of the real problem:
I changed the name portugol.y
to portugol.syn
and the problem has stoped!
--- bison -----------------------------------------------
bison --defines=y.tab.h --output=y.tab.c portugol.syn
---------------------------------------------------------
How is that? This indicates, in my opinion, that make has some default evaluation for files ".y" and now we need, to answer this question, to find out the root of this, and how to disable it. Thanks very much.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
问题是 make 具有从 .y 和 .l 文件构建 .c 文件的内置规则,正是这些内置规则被触发并导致您悲伤。
使用 GNU make,您可以通过用空白规则覆盖这些内置规则来禁用它们。将
你的 makefile 放在某个地方,你的问题就会消失。
您可以通过运行
make -p -f /dev/null
来查看 GNU make 的所有内置规则The problem is that make has built-in rules for building .c files from .y and .l files, and it is these builtin rules that are getting triggered and causing you grief.
With GNU make, you can disable these builtin rules by overriding them with blank rules. Put
in your makefile somewhere and your problems should go away.
You can see all of GNU make's built-in rules by running
make -p -f /dev/null
基本上,不要试图对抗系统。您需要能够创建
portugol.o
- 并拥有三个可能的源文件:portugol.l
、portugol.y
、portugol.c
。这至少多了两个。确保源文件的基本名称(减去扩展名)是唯一的。例如,使用
portugoll.l
、portugoly.y
和portugol.c
以及目标文件portugoll.o
>、portugoly.o
和portugol.o
。或者使用更长的后缀 -portugol-lex.l
、portugol-yacc.y
。或者portlex.l
、portyacc.y
或...Basically, do not try to fight the system. You need to be able to create
portugol.o
- and have three possible source files:portugol.l
,portugol.y
,portugol.c
. That is at least two too many.Make sure that the basenames of the source files (minus the extension) are unique. For example, use
portugoll.l
,portugoly.y
, andportugol.c
, with object filesportugoll.o
,portugoly.o
andportugol.o
. Or use longer suffixes -portugol-lex.l
,portugol-yacc.y
. Orportlex.l
,portyacc.y
, or ...谢谢乔纳森,
所以你看到了我也意识到的一个解决方案:更改文件名。但是,这就是问题的重点。我使用该脚本没有任何问题。如果我从 shell 脚本
flexyagcc.sh
调用bison -dy portugol.y
,它会给我y.tab.c
和y .tab.h
。为什么不从makefile
开始,这就是中心点!我确实喜欢我的文件名,它使一切变得如此连贯:
portugol.c
:手工例程,portugol.h
:头文件,portugol.l
:lex 扫描器和portugol.y
:解析器。另外,这不是我今天做的项目,多年来一直如此,有很多版本(现在是 3.0)。因此,无法更改文件名。除此之外,无论如何我最终都会得到portugol.c
!但这将是一个从 bison 自动生成的文件,又名 y.tab.c。因此,停止使用 portugol.c 来进行手工例程并开始使用相同的名称来进行解析器是非常令人困惑的。我只想知道 makefile 发生了什么,以及如何使用它来按原样替换脚本。不幸的是,虽然我不能,但我将使用该脚本。该脚本非常简单:
看,我什至懒得拥有目标
portugol.o
、y.tab.o
和lex.yy.o
。我直接在源代码上运行gcc
来跳过创建它们。如果在第一次尝试销毁我的portugol.c
后,我手动将创建的文件重命名为y.tab.c
,我也可以在 makefile 中执行此操作。所以问题是 makefile 与上面的脚本不同,它尝试创建以下内容:
portugol.l
对于两种情况(脚本和 makefile)y 更改。 tab.c
到portugol.c
(这里是问题!)portugol.c
更改为其他内容,例如portugol-funcs.c
感谢您的关注!
贝科
Thank you Jonathan,
So you see the one solution I've also perceived: change the name of the file. But, well, that is the point of the question. I have no problems using the script. If I call
bison -dy portugol.y
from the shell scriptflexyagcc.sh
it gives mey.tab.c
andy.tab.h
. Why not from amakefile
, that is the central point!I do like my file names, it makes all so coherent:
portugol.c
: handmade routines,portugol.h
:header file,portugol.l
:lex scanner, andportugol.y
: parser. Also, this is not a project I made today, it has being like that for years now, lots of versions (now 3.0). So, it is not an option to change the file names. Beside that, I would end up withportugol.c
anyway! But it would be a file automatically generated from bison, akay.tab.c
. So, it is very confusing to stop usingportugol.c
to have handmade routines, and start using the same name to have the parser.I just want to know what is happening with makefile, and how can I use it to substitute the script the way it is. While I can't, unfortunately, I'll be using the script. The script is very simple:
See, I don't even bother to have the objectives
portugol.o
,y.tab.o
andlex.yy.o
. I skip creating them by just running thegcc
on the sources directly. I also can do this in the makefile, if after the first attempt to destroy myportugol.c
, I rename manually the file created to bey.tab.c
.So the problem is that makefile differs from the above script by attempting to create the following:
portugol.l
for both cases (script and makefile)y.tab.c
toportugol.c
(here the problem!)portugol.c
to something else, likeportugol-funcs.c
Thanks for your kind attention!
Beco
奇怪的是,据我用小型临时文件进行测试,您遇到的问题是
提到的没有发生。
我的
make
版本是 GNU 3.80。供您参考,以下是我使用的
makefile
。希望这有帮助
Strangely, as far as I tested with small improvised files, the problem you
mentioned didn't occur.
My
make
's version is GNU 3.80.For your information, the following is the
makefile
I used.Hope this helps