grammar APL::Grammar is PCT::Grammar;

## C<TOP> defines the top level rule to the HLLCompiler
token TOP { <statement_list>  {*} }

token statement_list { ^<statement> [ \n <statement> ]* {*} }

token statement { <expression> [ \s*? $$ | <panic: 'Syntax error'> ] {*} }

token expression {
    | <target> '←' <expression> {*}                             #= assign
    | <monadic_identifier> <expression> {*}                     #= monadic
    | <subexpression> [ <dyadic_identifier> <expression> ]? {*} #= dyadic
}

token subexpression {
    <simple_expression> [ '[' <llist> ']' ]? {*}
}

token simple_expression {
    | <array_identifier> {*}                     #= array_identifier
    | '(' <expression> ')' {*}                   #= expression
}

token target { <variable_identifier> [ '[' <llist> ']' ]? {*} }

token llist { $0=(<expression>?) $0=( ';' <expression>? )* }

token dyadic_identifier  { <[|⍟*⌈⌊○!+−×÷~∧∨⍲⍱<≤=≥>≠⍳⊖↑↓⍴⍕]> }

token monadic_identifier {
    '⎕←' |
    <[|⍟*⌈⌊○!+−×÷~⍳⌽↑⍴⍕]>
}

token array_identifier {
    | <constant> {*}                             #= constant
    | <variable_identifier> {*}                  #= variable_identifier
}

token constant {
    | <character_constant_double> {*}            #= character_constant_double
    | <character_constant_single> {*}            #= character_constant_single
    | <numeric_constant> {*}                     #= numeric_constant
}


token numeric_constant {
    <decimal_representation> [ \s+ <decimal_representation> ]*
    {*}
}


token decimal_representation {
    [ '⁻'? \d+ '.'? \d* | '⁻'? '.' \d+ ] [ 'E' '⁻'? \d+ ]?
    {*}
}

token character_constant_double { \" ( [ \"\" | <-["]> ]* ) \" {*} }
token character_constant_single { \' ( [ \'\' | <-[']> ]* ) \' {*} }

token variable_identifier { <[A..Za..z]> <[A..Za..z0..9_]>* {*} }
