<!--  vim: set sw=2 sts=2 et ft=docbk:

  Part of the A-A-P recipe executive: Recipe Syntax

  Copyright (C) 2002-2003 Stichting NLnet Labs
  Permission to copy and use this file is specified in the file COPYING.
  If this file is missing you can find it here: http://www.a-a-p.org/COPYING

-->

<para>
This defines the recipe syntax.  It is not very strict, but you should be able
to understand what is allowed and what isn't.
</para>

<para>
The intention is that recipes are always encoded in UTF-8.  Currently this is
not fully supported yet.  US-ASCII works in any case.
</para>

<para>
<table frame="none">
<title>Notation</title>
<tgroup cols="2"><tbody>
   <row><entry>|</entry><entry>separates alternatives</entry></row>
   <row><entry>()</entry><entry>grouping a sequence of items or alternatives</entry></row>
   <row><entry>[]</entry><entry>optional items (also does grouping)</entry></row>
   <row><entry>""</entry><entry>contains literal text;  """ is one double quote</entry></row>
   <row><entry>...</entry><entry>indicates the preceding item or group can be repeated</entry></row>
   <row><entry>EOL</entry><entry>an end-of-line, optionally preceded by a comment</entry></row>
   <row><entry>INDENT&nbsp;&nbsp;</entry><entry>an amount of white space, at least one space</entry></row>
   <row><entry>INDENT2&nbsp;&nbsp;</entry><entry>an amount of white space, at least one space more than INDENT</entry></row>
</tbody></tgroup></table>
</para>

<para>
A comment starts with "#" and continues until the end-of-line.  It continues
in the next line if the last character in the line is a backslash.
A comment may appear where white space may appear, but not inside quotes.
</para>

<programlisting>
        # comment \
        continued comment
        # another comment
</programlisting>

<para>
White space may be inserted in between items.
It is often ignored, but does have a meaning in a few places.
</para>

<para>
Line continuation may be done with a backslash immediately before an
end-of-line.  It is not needed for items that use extra indent to indicate
that it continues on the next line.
</para>

<para>
The backslash can be also used for line continuation in Python commands.
A leading @ char and white space before it is removed.
Example:
</para>

<programlisting>
        @ python command \
        @   continued python command \
               still continued
</programlisting>

<para>
When lines are joined because a command continues in a line with more indent,
the line break and leading white space of the next line are replaced with a
single space.  An exception is when the line ends in "$BR": The $BR is
removed, the line break is inserted in the text and leading white space of the
next line is removed.
</para>

<para>
All indent is computed with a tabstop setting of eight spaces.
</para>

<para>
For items that have a build_block, the start of the build block is the line
with the smallest indent that is larger than the indent of the line that
started the item.  The lines before this are continuation lines of the command
itself.  Example:
</para>
<programlisting>
        mytarget : source1
                      source2   # continuation line of dependency
            :print $source      # first line of the build block
                 something      # continuation line of :print command
</programlisting>

<informaltable frame="none"><tgroup cols="3">
<colspec colname='c1' colwidth="150"/>
<colspec colname='c2' colwidth="040"/>
<colspec colname='c3' colwidth="700"/>
<tbody>
   <row>
      <entry valign="top">aapfile</entry>
      <entry valign="top">::=</entry>
      <entry valign="top">( [ aap_item ] EOL ) ...</entry>
   </row>
   <row>
      <entry valign="top">aap_item</entry>
      <entry valign="top">::=</entry>
      <entry valign="top">dependency | rule |
                  variant | toplevel_command | build_command</entry>
   </row>
   <row>
      <entry>&nbsp;</entry>
   </row>
   <row>
      <entry valign="top">dependency</entry>
      <entry valign="top">::=</entry>
      <entry valign="top">targets ":" [ attribute ... ] [ sources ] [ EOL build_block ]</entry>
   </row>
   <row>
      <entry valign="top">targets</entry>
      <entry valign="top">::=</entry>
      <entry valign="top">item_list</entry>
   </row>
   <row>
      <entry valign="top">sources</entry>
      <entry valign="top">::=</entry>
      <entry valign="top">item_list</entry>
   </row>
   <row>
      <entry valign="top">build_block</entry>
      <entry valign="top">::=</entry>
      <entry valign="top">INDENT build_command [ EOL [ INDENT build_command ] ] ...</entry>
   </row>
   <row>
      <entry>&nbsp;</entry>
   </row>
   <row>
      <entry valign="top">rule</entry>
      <entry valign="top">::=</entry>
      <entry valign="top">
        <link linkend="cmd-rule">:rule</link> [ attribute ... ] pattern ... ":" [ attribute ... ] pattern ... [ EOL build_block ]</entry>
   </row>
   <row>
      <entry>&nbsp;</entry>
   </row>
   <row>
      <entry valign="top">variant</entry>
      <entry valign="top">::=</entry>
      <entry valign="top">
        <link linkend="cmd-variant">":variant"</link> variable_name ( EOL variant_item ) ...</entry>
   </row>
   <row>
      <entry valign="top">variant_item</entry>
      <entry valign="top">::=</entry>
      <entry valign="top">INDENT varvalue EOL INDENT2 build_block</entry>
   </row>
   <row>
      <entry>&nbsp;</entry>
   </row>
   <row>
      <entry valign="top">toplevel_command</entry>
      <entry valign="top">::=</entry>
      <entry valign="top">child_command |
                          clearrules_command |
                          delrule_command |
                          dll_command |
                          lib_command |
                          program_command |
                          recipe_command |
                          route_command |
                          rule_command |
                          totype_command |
                          variant_command </entry>
   </row>
   <row>
      <entry>&nbsp;</entry>
   </row>
   <row>
      <entry valign="top">build_command</entry>
      <entry valign="top">::=</entry>
      <entry valign="top">assignment | block_assignment | python_item | generic_command</entry>
   </row>
   <row>
      <entry>&nbsp;</entry>
   </row>
   <row>
      <entry valign="top">assignment</entry>
      <entry valign="top">::=</entry>
      <entry valign="top">variable_name [ "$" ] ( "=" | "+=" | "?=" ) item_list</entry>
   </row>
   <row>
      <entry valign="top">block_assignment</entry>
      <entry valign="top">::=</entry>
      <entry valign="top">variable_name [ "$" ] ( "&lt;&lt;" | "+&lt;&lt;" |
      "?&lt;&lt;" ) marker ( EOL item_list ) ... EOL [ INDENT ] marker</entry>
   </row>
   <row>
      <entry>&nbsp;</entry>
   </row>
   <row>
      <entry valign="top">python_item</entry>
      <entry valign="top">::=</entry>
      <entry valign="top">python_line | python_block </entry>
   </row>
   <row>
      <entry valign="top">python_line</entry>
      <entry valign="top">::=</entry>
      <entry valign="top">"@" python_command</entry>
   </row>
   <row>
      <entry valign="top">python_block</entry>
      <entry valign="top">::=</entry>
      <entry valign="top">
        <link linkend="cmd-python">":python"</link> EOL ( INDENT python_command EOL ) ...</entry>
   </row>
   <row>
      <entry>&nbsp;</entry>
   </row>
   <row>
      <entry valign="top">generic_command</entry>
      <entry valign="top">::=</entry>
      <entry valign="top">":" command_name [ command_argument ] </entry>
   </row>
   <row>
      <entry>&nbsp;</entry>
   </row>
   <row>
      <entry>&nbsp;</entry>
   </row>
   <row>
      <entry namest="c1" nameend="c3"># An item_list can contain white-separated items and Python style expressions.</entry>
   </row>
   <row>
      <entry>&nbsp;</entry>
   </row>
   <row>
      <entry valign="top">item_list</entry>
      <entry valign="top">::=</entry>
      <entry valign="top">item [ white_space item ] ...</entry>
   </row>
   <row>
      <entry valign="top">item</entry>
      <entry valign="top">::=</entry>
      <entry valign="top">simple_item [ attribute ... ]</entry>
   </row>
   <row>
      <entry valign="top">simple_item</entry>
      <entry valign="top">::=</entry>
      <entry valign="top">( expression | non_white_item ) ...</entry>
   </row>
   <row>
      <entry valign="top">attribute</entry>
      <entry valign="top">::=</entry>
      <entry valign="top">"{" attribute_name [ "=" item_list ] "}"</entry>
   </row>
   <row>
      <entry valign="top">expression</entry>
      <entry valign="top">::=</entry>
      <entry valign="top">string_expr | python_expr</entry>
   </row>
   <row>
      <entry valign="top">string_expr</entry>
      <entry valign="top">::=</entry>
      <entry valign="top">""" text """ | "'" text "'"</entry>
   </row>
   <row>
      <entry valign="top">python_expr</entry>
      <entry valign="top">::=</entry>
      <entry valign="top">"`" python-expression "`"</entry>
   </row>
   <row>
      <entry valign="top">non_white_item</entry>
      <entry valign="top">::=</entry>
      <entry valign="top">non-white-text | variable_reference</entry>
   </row>
   <row>
      <entry valign="top">variable_reference</entry>
      <entry valign="top">::=</entry>
      <entry valign="top">"$" [ expand_type ] ...
                     (variable_ext_name
                     | "(" variable_ext_name ")"
                     | "{" variable_ext_name "}" )
                    </entry>
   </row>
   <row>
      <entry valign="top">expand_type</entry>
      <entry valign="top">::=</entry>
      <entry valign="top">"?" | "-" | "+" | "*" | "=" | "'" | '"' | "\" | "!" </entry>
   </row>
   <row>
      <entry valign="top">variable_ext_name</entry>
      <entry valign="top">::=</entry>
      <entry valign="top">[ scope_name "." ] variable_name [ "[" index "]" ] </entry>
   </row>
   <row>
      <entry valign="top">variable__name, attribute_name</entry>
      <entry valign="top">::=</entry>
      <entry valign="top">ascii-letter [ ascii-letter | ascii-number | "_" ] ... </entry>
   </row>
   <row>
      <entry valign="top">scope_name</entry>
      <entry valign="top">::=</entry>
      <entry valign="top">( "_no" | "_stack" | "_tree" | "_up"
                            | "_recipe" | "_top" | "_default" | "_start"
                            | "_parent" | "_caller" | user_scope_name )</entry>
   </row>
   <row>
      <entry valign="top">user_scope_name</entry>
      <entry valign="top">::=</entry>
      <entry valign="top">ascii-letter [ ascii-letter | ascii-number | "_" ] ... </entry>
   </row>

</tbody></tgroup></informaltable>


