## AEL version 2 BNF

(hopefully, something close to bnf).

First, some basic objects

-     ------------------------
      <word>    a lexical token consisting of characters matching this pattern: [-a-zA-Z0-9"_/.\<\>\*\+!$#\[\]][-a-zA-Z0-9"_/.!\*\+\<\>\{\}$#\[\]]*

      <word3-list>  a concatenation of up to 3 <word>s.

      <collected-word>  all characters encountered until the character that follows the <collected-word> in the grammar.
      -------------------------

      <file> :== <objects>

      <objects> :== <object>
                 | <objects> <object>

      <object> :==  <context>
               | <macro>
               | <globals>
               | ';'

      <context> :==  'context' <word> '{' <elements> '}'
                  | 'context' <word> '{' '}'
                  | 'context' 'default' '{' <elements> '}'
                  | 'context' 'default' '{' '}'
                  | 'abstract'  'context' <word> '{' <elements> '}'
                  | 'abstract'  'context' <word> '{' '}'
                  | 'abstract'  'context' 'default' '{' <elements> '}'
                  | 'abstract'  'context' 'default' '{' '}'

      <macro> :== 'macro' <word> '(' <arglist> ')' '{' <macro_statements> '}'
             | 'macro' <word> '(' <arglist> ')' '{'  '}'
             | 'macro' <word> '(' ')' '{' <macro_statements> '}'
             | 'macro' <word> '(' ')' '{'  '}'

      <globals> :== 'globals' '{' <global_statements> '}'
               | 'globals' '{' '}'

      <global_statements> :== <global_statement>
                         | <global_statements> <global_statement>

      <global_statement> :== <word> '=' <collected-word> ';'

      <arglist> :== <word>
               | <arglist> ',' <word>

      <elements> :==  <element>
                   | <elements> <element>

      <element> :== <extension>
               | <includes>
               | <switches>
               | <eswitches>
               | <ignorepat>
               | <word> '='  <collected-word> ';'
               | 'local' <word> '='  <collected-word> ';'
               | ';'

      <ignorepat> :== 'ignorepat' '=>' <word> ';'

      <extension> :== <word> '=>' <statement>
                 | 'regexten' <word> '=>' <statement>
                 | 'hint' '(' <word3-list> ')' <word> '=>' <statement>
                 | 'regexten' 'hint' '(' <word3-list> ')' <word> '=>' <statement>

      <statements> :== <statement>
                  | <statements> <statement>

      <if_head> :== 'if' '('  <collected-word> ')'

      <random_head> :== 'random' '(' <collected-word> ')'

      <ifTime_head> :== 'ifTime' '(' <word3-list> ':' <word3-list> ':' <word3-list> '|' <word3-list> '|' <word3-list> '|' <word3-list> ')'
                             | 'ifTime' '(' <word> '|' <word3-list> '|' <word3-list> '|' <word3-list> ')'

      <word3-list> :== <word>
             | <word> <word>
             | <word> <word> <word>

      <switch_head> :== 'switch' '(' <collected-word> ')'  '{'

      <statement> :== '{' <statements> '}'
             | <word> '='  <collected-word> ';'
             | 'local' <word> '='  <collected-word> ';'
             | 'goto' <target> ';'
             | 'jump' <jumptarget> ';'
             | <word> ':'
             | 'for' '('  <collected-word> ';'  <collected-word> ';' <collected-word> ')' <statement>
             | 'while' '('  <collected-word> ')' <statement>
             | <switch_head> '}'
             | <switch_head> <case_statements> '}'
             | '&' macro_call ';'
             | <application_call> ';'
             | <application_call> '='  <collected-word> ';'
             | 'break' ';'
             | 'return' ';'
             | 'continue' ';'
             | <random_head> <statement>
             | <random_head> <statement> 'else' <statement>
             | <if_head> <statement>
             | <if_head> <statement> 'else' <statement>
             | <ifTime_head> <statement>
             | <ifTime_head> <statement> 'else' <statement>
             | ';'

      <target> :== <word>
             | <word> '|' <word>
             | <word> '|' <word> '|' <word>
             | 'default' '|' <word> '|' <word>
             | <word> ',' <word>
             | <word> ',' <word> ',' <word>
             | 'default' ',' <word> ',' <word>

      <jumptarget> :== <word>
                     | <word> ',' <word>
                     | <word> ',' <word> '@' <word>
                     | <word> '@' <word>
                     | <word> ',' <word> '@' 'default'
                     | <word> '@' 'default'

      <macro_call> :== <word> '(' <eval_arglist> ')'
             | <word> '(' ')'

      <application_call_head> :== <word>  '('

      <application_call> :== <application_call_head> <eval_arglist> ')'
             | <application_call_head> ')'

      <eval_arglist> :==  <collected-word>
             | <eval_arglist> ','  <collected-word>
             |  /* nothing */
             | <eval_arglist> ','  /* nothing */

      <case_statements> :== <case_statement>
             | <case_statements> <case_statement>

      <case_statement> :== 'case' <word> ':' <statements>
             | 'default' ':' <statements>
             | 'pattern' <word> ':' <statements>
             | 'case' <word> ':'
             | 'default' ':'
             | 'pattern' <word> ':'

      <macro_statements> :== <macro_statement>
             | <macro_statements> <macro_statement>

      <macro_statement> :== <statement>
             | 'catch' <word> '{' <statements> '}'

      <switches> :== 'switches' '{' <switchlist> '}'
             | 'switches' '{' '}'

      <eswitches> :== 'eswitches' '{' <switchlist> '}'
             | 'eswitches' '{'  '}'

      <switchlist> :== <word> ';'
             | <switchlist> <word> ';'

      <includeslist> :== <includedname> ';'
             | <includedname> '|' <word3-list> ':' <word3-list> ':' <word3-list> '|' <word3-list> '|' <word3-list> '|' <word3-list> ';'
             | <includedname> '|' <word> '|' <word3-list> '|' <word3-list> '|' <word3-list> ';'
             | <includeslist> <includedname> ';'
             | <includeslist> <includedname> '|' <word3-list> ':' <word3-list> ':' <word3-list> '|' <word3-list> '|' <word3-list> '|' <word3-list> ';'
             | <includeslist> <includedname> '|' <word> '|' <word3-list> '|' <word3-list> '|' <word3-list> ';'

      <includedname> :== <word>
              | 'default'

      <includes> :== 'includes' '{' <includeslist> '}'
             | 'includes' '{' '}'