Я пишу грамматику, которая называется 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
, который делает это. Нет ошибок в процессе.
Итак, теперь я решил выучить makefile
.
Проблема, с которой я сталкиваюсь, заключается в том, что по какой-то странной причине "bison -dy
", которую я вызвал, сопровождается командой, которую я не писал: mv -f y.tab.c portugol.c
Ну, это уничтожает мой исходный файл ручной работы!
Я перепробовал все, что мог, но не смог избавиться от этого "mv
".
Я даже сделал sleep
и попробовал:
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
Безуспешно.
Ну, прежде чем я сдался, я решил использовать стандартный вывод зубров. Итак, я бы имел:
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
?
Спасибо!
Бек
PS- Отредактировано. Использование:
Ubuntu 10.04.2 LTS
GNU Make 3.81
PPS. Ред. Незначительные опечатки.
PPPS. Ред. Отвечая на Ise wisteria:
Спасибо за ваш ответ. Я сохранил твой make-файл как makefile2 и попробовал. Ответ, который я получил от марки:
$ 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
Я также отметил, что «сегодня» второй вызов бизона - это не вызов бизона, а вызов yacc. Может быть, мы говорим о некоторой переменной среды здесь? Это также меняется с моим make-файлом:
$ 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
$
Вот мой полный make-файл:
# 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», и теперь нам нужно, чтобы ответить на этот вопрос, выяснить корень этого и узнать, как его отключить. Большое спасибо.