%% "Smith, Jack" <[EMAIL PROTECTED]> writes:
sj> I was hoping that you could help me with a little issue I am
sj> working on. I am trying to write a utility that will analyse a
sj> makefile, and create a target 'tree' from it.
I think your best bet is to hack GNU make itself; after it finishes
reading the makefile, have it print the tree you're looking for rather
than run any rules.
sj> In preparation for this, I thought I would write out the
sj> Backus-Nour Fom of the various elements of a makefile, so that I
sj> could structure my app efficiently.
Eh. Good luck.
sj> I have enclosed my best analysis of the make document from the GNU
sj> manuals online. Below is the result of the first stab at BNF for
sj> an explicit rule. Could you kindly have a look at it,, and tell
sj> me if you see any errors.
All over :).
Writing a BNF for makefiles is a Herculean task.
sj> rule: how to work with a target ( note: a rule may contain zero to many
sj> targets )
First, note you've not dealt with the issue of make variables anywhere
here. Make variables are expanded essentially anywhere and can contain
almost anything.
sj> from http://www.gnu.org/manual/make-3.77/html_mono/make.html#SEC20
sj> In general, a rule looks like this:
sj> targets : dependencies
sj> command
sj> ...
sj> or like this:
sj> targets : dependencies ; command
sj> command
sj> ...
Yes, but there's a _LOT_ left unsaid here.
sj> So from this we infer the following BNF statement
sj> (* a rule must start at the first character on a new line - no
sj> whitespace may proceed the identifier name of the rule*)
Not true. A rule can begin anywhere on the line, it doesn't have to
start in the first column. The only requirement is that the first
character of the line _NOT_ be a TAB. The first character could be a
SPC and the second character could be a TAB; that's fine.
sj> rule = whitespace-, name,":",[dependancy-list],
sj> ([command-seperator], [command-list])
You can have multiple targets in a rule. Here you have just one.
Also, there can be zero or more whitespace chars between the target
names, the ":", and the dependency list. You don't show that here.
Does normal BNF have commas between elements? I don't recall that being
the case. Oh well.
sj> name = letter, {letter | decimal-digit | full-stop };
In make, a target or dependency name can contain _any_ character except
for whitespace, ":", and "=", IIRC. Maybe not ";" either; I'd have to
check.
The most obvious ones you've forgotten are underscore and dash, but
people also use "+", etc.
sj> dependancy-list = [name], { (dependancy-seperator, name) };
sj> dependancy-seperator = {whitespace}, ",", {whitespace};
Dependencies aren't separated by commas, they're separated by
whitespace. Ditto for targets (above).
sj> (* when a command starts on a new line, it must be proceeded by a
sj> horizontal tabulation character*)
To be precise, the TAB must be the first character on the line of every
command. There can be extra whitespace after the TAB, but the TAB must
be first.
sj> command-list = command, {(command-seperator, command)};
sj> command = name, [argument-list];
sj> command-seperator = ";" | (new-line-char, horiz-tab-char);
sj> argument-list = name; {(whitespace, name)}
You won't be able to specify this very well. A command can be _any_
shell command. You're not allowing for probably 80% of the possible
shell commands here; you don't allow for pipes, redirection, etc. etc.
To make, the contents of the command are just a black box. It simply
reads text until the end of the line, then when it runs the rule it
passes that text to the shell. The _only_ parsing it does is to replace
variables. I suggest you follow that lead in your BNF, as well.
sj> whitespace = " " | horiz-tab-char;
sj> full-stop = ".";
Of course, you also haven't dealt with escaped newlines, like this:
foo: bar \
baz
echo hi \
there
--
-------------------------------------------------------------------------------
Paul D. Smith <[EMAIL PROTECTED]> Find some GNU make tips at:
http://www.gnu.org http://www.ultranet.com/~pauld/gmake/
"Please remain calm...I may be mad, but I am a professional." --Mad Scientist