Anvil | Smiths Smiths | Register Register | Login Login |
Search:
Show links Show tools Show tree | Previous document Next document | njet.org > Anvil > Documentation > Language reference > Grammar

Grammar

This grammar does not pretend to be well formed. It tries to be more readable, omitting ambiquity and precendence issues. Some of the rules has been repeated for clarity. Short reference to syntax:

  • A   A is rule
  • AN    A is rule and N is (informal) name for rule
  • A B .. means sequence
  • ( A B ..) means sequence
  • ( A | B | .. | C ) means choose one from
  • [ A ] means A is optional
  • A ? means A is optional
  • A * means A can repeat 0..N times
  • A + means A must repeat 1..N times


  module := "module" [ symbolname ] "{" module-decls "}" 
  module :=  module-decls 
  module-decls =  
    ( import  
    | constant  
    | variable  
    | function  
    | namespace 
    | class  
    | interface ) * 

  import        := "import" import-source [ import-as ] ";" 
  import        := "import" import-source ":" import-list ";" 
  import-name   := symbol ( "." symbol )* 
  import-source := ( string-literalpath | import-name ) 
  import-as     := "as" symbolnewname 
  import-list   := "*" 
  import-list   := import-entity  ( "," import-entity )* 
  import-entity := import-name ["." "*"] [ import-as ] 

  constant      := "const" constant-decl ( "," constant-decl )* ";" 
  constant-decl := symbolname "=" exprinitializer 

  variable      := "var" variable-decl ( "," variable-decl )* ";" 
  variable-decl := symbolname [ "=" exprinitializer ] 

  namespace :=  
    "namespace" namespace-name   
    "{" 
       ( import 
       | constant  
       | variable  
       | function  
       | namespace  
       | class ) *  
    "}" 
  namespace-name := symbol ( "." symbol )* 

  entity := ( "module" "." symbol | symbol ) ( "." symbol ) * 
  class  :=  
    "class" symbolname  
    [ "extends" entityclass ]  
    [ "implements" entityinterface ( "," entityinterface )* ] 
    "{"  
      ( import 
      | constant  
      | variable  
      | function  
      | "static" variable  
      | "static" function  
      | class  
      )*  
    "}" 

  entity := ( "module" "." symbol | symbol ) ( "." symbol ) * 
  interface :=  
    "interface" symbolname   
    "extends" [ entityinterface ( "," entityinterface ) * ] 
    "{"  
       ( import 
       | constant  
       | variable 
       | "static" function 
       | interface-method  
       | interface 
       )*  
    "}" 

  arguments        := [ argument ( "," argument )* ] [ ".." symbolcollector ] 
  argument         := symbolname [ = exprconstant ] 
  interface-method := "function" symbolname  "(" arguments ")" ";" 

  arguments := [ argument ( "," argument )* ] [ ".." symbolcollector ] 
  argument  := symbolname [ = exprconstant ] 
  function  :=  
    ["synchronized"] "function" symbolname "(" arguments ")"  
    "{"  
      ( function  
      | import  
      | statement ) *  
    "}" 

  arguments        := [ argument ( "," argument )* ] [ ".." symbolcollector ] 
  argument         := symbolname [ = exprconstant ] 
  inline-function := "{" "|" arguments "|" statement * "}" 
  inline-function := "{" "||" statement * "}" 

  statement := 
    ( assert 
    | break 
    | catch 
    | continue 
    | empty 
    | exit 
    | expr-stmt 
    | finally 
    | if 
    | print 
    | return 
    | synchronized 
    | throw 
    | try 
    | yield 
    | [ label ] block  
    | [ label ] do 
    | [ label ] for 
    | [ label ] foreach 
    | [ label ] switch 
    | [ label ] while 
    ) 

  assert := "assert" exprcondition ";" 

  break  := "break" [ symbollabel ] [ stmt-modifier ] ";" 

  continue  := "continue" [ symbollabel ] [ stmt-modifier ] ";" 
  continue  := "continue" [ symbollabel ] "case" exprconstant  [ stmt-modifier ] ";" 
  continue  := "continue" [ symbollabel ] "default" [ stmt-modifier ] ";" 

  empty := ";" 

  exit := "exit" [ expr-listvalues ] [ stmt-modifier ] ";" 

  expr-stmt := expr-start [ stmt-modifier ] ";" 

  print := ("print" | "println" | "printbr" )  
           [ print-expr-listvalues ] [ stmt-modifier ] ";" 
  print-expr-list := expr-start ( ( "," )+ expr-start ) * 

  return := "return" [ expr-listvalues ] [ stmt-modifier ] ";" 

  throw := "throw" expr-listthrowable [ stmt-modifier ] ";" 

  yield := "yield" expr-listvalues [ stmt-modifier ] ";" 

  stmt-modifier := ( "if" exprcondition | "while" exprcondition ) 

  label := symbollabel ":" 

  block  := "{" statement * "}" 

  catch := "catch" "(" assignable-exprthrowable ")" statement 
  catch := "catch" "(" assignable-exprthrowable ":" identifiertype ")" statement 
  catch := "catch" "(" assignable-exprthrowable ":" expressioncondition ")" statement 

  do := "do" statement "while" "(" expr-startcondition ")" ";" 

  finally := "finally" statement 

  for := "for" "(" exprs ")" statement 
  for-exprs := [ for-expr-listinit ] ";" [ exprcondition ] ";" [ for-expr-listaction ]  
  for-expr-list := expr-start ( "," expr-start ) * 

  foreach :=  
    "foreach" "(" [[[[ foreach-expr-listindices ] ";"]  
                     [ foreach-expr-listkeys    ] ";"]  
                     [ foreach-expr-listvalues  ] ";"] expriterable ")" statement 
  foreach-expr-list := assignable-exprtarget ( "," assignable-exprtarget ) * 

  if := "if" "(" expr-startcondition ")" statementthen [ "else" statementelse ] 

  switch :=  
    "switch" "(" expr-startcandidate ")"  
    "{" 
      ( "case" exprvalue ( "," exprvalue )* ":"  statement * 
      | "default" ":" statement * 
      ) * 
    "}" 

  synchronized := "synchronized" "(" expr-startobject ")" statement 

  try := "try" statement ( catch )* [ finally ] 

  while := "while" "(" expr-startcondition ")" statement 

  expr-start := assignment | expr 
  expr-list  := expr ( "," expr )* 

  assignable-expr := ["&"] identifier accessor 
  assign-target   := assignable-expr 
  assign-targets  := assign-target ("," assign-target ) * 
  assignment      := assign-targets "=" expr-list 
  assignment      := assign-targets "+=" expr-list 
  assignment      := assign-targets "-=" expr-list 
  assignment      := assign-targets "*=" expr-list 
  assignment      := assign-targets "/=" expr-list 
  assignment      := assign-targets "%=" expr-list 
  assignment      := assign-targets "&=" expr-list 
  assignment      := assign-targets "?=" expr-list 

  expr :=  
    foreach-expr 
  | pipe-expr 
  | map-expr 
  | cond-expr 
  | range-expr 
  | or-expr 
  | xor-expr 
  | and-expr 
  | eq-expr 
  | rel-expr 
  | in-expr 
  | add-expr 
  | mul-expr 
  | match-expr 
  | unary-expr 
  | cast-expr 
  | augment-expr 
  | is-expr 
  | has-expr 
  | lazy-expr 
  | primary 

  foreach-expr := expr "foreach" inline-function  

  pipe-expr := expriterable "->" exprcallable 

  map-expr := exprkey "=>" exprvalue 

  cond-expr := exprcondition "?" exprif-true ":" exprif-false 
  cond-expr := exprcondition "?" exprif-true ":"  
  cond-expr := exprvalue "??" exprif-false 

  range-expr := exprstart ".." exprend 
  range-expr := exprstart ".." 
  range-expr := ".." exprend 
  range-expr := ".." 

  or-expr  := expr "||" expr 
  xor-expr := expr "^^" expr 
  and-expr := expr "&&" expr 

  eq-expr := expr "==" expr 
  eq-expr := expr "!=" expr 
  eq-expr := expr "===" expr 
  eq-expr := expr "!==" expr 
  eq-expr := expr "<=>" expr 
  eq-expr := expr "<==>" expr 

  rel-expr := expr ">" expr 
  rel-expr := expr ">=" expr 
  rel-expr := expr "<" expr 
  rel-expr := expr "<=" expr 

  in-expr := exprelement "in" exprset 
  in-expr := exprelement "!" "in" exprset 

  add-expr := expr "+" expr 
  add-expr := expr "-" expr 
  add-expr := expr "&" expr 

  mul-expr := expr "*" expr 
  mul-expr := expr "/" expr 
  mul-expr := expr "%" expr 

  match-expr := exprcandidate "~" exprpattern 
  match-expr := exprcandidate "!~" exprpattern 

  unary-expr := "!" expr 
  unary-expr := "+" expr 
  unary-expr := "-" expr 
  unary-expr := "*" expriterable 
  unary-expr := "copyof" exprcopyable 
  unary-expr := "cloneof" exprcloneable 
  unary-expr := "sizeof" expr 
  unary-expr := "classof" expr 

  cast-expr := "(" "boolean" ")" expr 
  cast-expr := "(" "int" ")" expr 
  cast-expr := "(" "float" ")" expr 
  cast-expr := "(" "string" ")" expr 

  augment-expr := "++" assignable-expr 
  augment-expr := "--" assignable-expr 
  augment-expr := assignable-expr "++" 
  augment-expr := assignable-expr "--" 

  is-expr := expr "is" ["!"] "defined" 
  is-expr := expr "is" ["!"] "undefined" 
  is-expr := expr "is" ["!"] "null" 
  is-expr := expr "is" ["!"] "boolean" 
  is-expr := expr "is" ["!"] "int" 
  is-expr := expr "is" ["!"] "float" 
  is-expr := expr "is" ["!"] "string" 
  is-expr := expr "is" ["!"] "&" 
  is-expr := expr "is" ["!"] ".." 
  is-expr := expr "is" ["!"] "=>" 
  is-expr := expr "is" ["!"] "(" ")" 
  is-expr := expr "is" ["!"] "{" "}" 
  is-expr := expr "is" ["!"] "[" "]" 
  is-expr := expr "is" ["!"] "class" 
  is-expr := expr "is" ["!"] entityclass-of-interface 

  has-expr := expr "has" ["!"] symbolname 
  has-expr := expr "has" ["!"] "(" expr ")" 

  lazy-expr := "^" primary 

  primary :=  
    ( parenthesized 
    | literal 
    | import-expr 
    | defined-expr 
    | delete-expr 
    | list-expr 
    | tuple-expr 
    | array-expr 
    | type-expr 
    | new-expr 
    | inline-function  
    | call-expr 
    | ref-expr 
    | identifier ) accessor * 

  parenthesized := "(" expr ")" 

  import-expr := import "(" exprpath ")" 

  defined-expr := "defined" identifier  
  defined-expr := "defined" "(" identifier ")" 

  delete-expr := "delete" identifier  
  delete-expr := "delete" "(" identifier ")" 

  tuple-expr := "(" ")" 
  tuple-expr := "(" expr "," ")" 
  tuple-expr := "(" expr-list [","] ")" 

  list-expr := "\{" expr-list [","] "}" 
  list-ctor := "\{" comprehension-foreach  "}" 
  comprehension-foreach :=  "foreach" "(" ... ")" comprehension 
  comprehension-if ::= "if" "(" expr ")" comprehension 
  comprehension := comprehension-foreach | comprehension-if | expr 

  array-expr := "[" array-mapping ("," array-mapping )* [","] "]" 
  array-expr := "[" comprehension-foreach "]" 
  array-mapping := exprkey ["=>" exprvalue ] 
  comprehension-foreach :=  "foreach" "(" ... ")" comprehension 
  comprehension-if ::= "if" "(" expr ")" comprehension 
  comprehension := comprehension-foreach | comprehension-if | expr 

  type-expr := ( "boolean" | "int" | "float" | "string" ) 

  new-expr := "new" identifierclass "(" parameters ")" 
  new-expr := "new" identifierclass  inline-functionparameter   
  param := [ symbolname "=" | "@" ] expr 
  parameters := param ( "," param )* 

  identifier :=  
    [ "var" ] 
    [ symbol | "module" | "class" | "static" | "this" | "super" ] 
    ( "." ( symbol | "this" ) ) * 
    [ "." ( "class"  
          | "sizeof" 
          | "copyof" 
          | "cloneof" ) 
    ] 

  call-expr :=  identifiercallable "(" parameters ")" 
  call-expr :=  identifiercallable  inline-functionparameter    
  parameters := param ( "," param )* 
  param := [ symbolname "=" | "@" ] expr 

  ref-expr := "&" identifierlocal-or-parameter 

  accessor :=  
    acc-call 
  | acc-closure-call 
  | acc-invoke 
  | acc-attribute 
  | acc-reference  

  acc-call   := "(" parameters ")" 
  parameters := param ( "," param )* 
  param := [ symbolname "=" | "@" ] expr 
  acc-closure-call := inline-functionparameter 

  acc-invoke := "." symbolname "(" parameters ")" 
  acc-invoke := "." "(" expr ")" "(" parameters ")" 
  acc-invoke := "." symbolname  inline-functionparameter  
  acc-invoke := "." "(" expr ")" inline-functionparameter 
  parameters := param ( "," param )* 
  param := [ "@" ] expr 

  acc-attribute  := "." symbolattribute-name 

  acc-reference  := "[" expr-list "]" 
  acc-reference  := "[" "]" 

  literal :=  
    int-literal 
  | float-literal 
  | string-literal 
  | pattern-literal 
  | "inf" 
  | "false" 
  | "true" 
  | "undefined" 

See also  | Language reference
Contributes notes:
Add a note
What's new | Anvil