%% "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

Reply via email to