# Asterisk Project : AEL version 2 BNF

Added by mdavenport , edited by mdavenport on Aug 31, 2010

(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' '{' '}'