beans 6.6.0

A parser generator library based on the Earley parser
Documentation
Option[content] ::=
  content@value <Some>
  <None>;

NonEmptyList[content, separation] ::=
  content@head <Nil>
  content@head separation NonEmptyList[content, separation]@tail <Cons>;

List[content, separation] ::=
  Option[NonEmptyList[content, separation]]@value <>;

Empty ::=
  <>;

"a file"
@File ::=
  List[INCLUDE, Empty] List[FunctionDeclaration, Empty]@decls <>;

"a function declaration"
FunctionDeclaration ::=
  Type@rettype IDENT.0@name LPAR List[TypedParam, COMMA]@args RPAR Block@block <>;

"a type"
Type ::=
  VOID <Void>
  INTTY <Int>
  BOOL <Bool>
  Type@pointed ASTERISK <Pointer>;

"a parameter"
TypedParam ::=
  Type@type IDENT.0@name <>;

"an integer"
Int ::=
  INT.0@value <Int>
  CHAR.0@value <Char>;

"a boolean"
Bool ::=
  TRUE <True>
  FALSE <False>;

"an expression"
Expr ::=
  Int@value <Int>
  Bool@value <Bool>
  NULL <Null>
  LPAR Expr@this RPAR <Through>
  EXCLAM Expr@value <Not>
  PLUSPLUS Expr@value <Incrl>
  Expr@value PLUSPLUS <Incrr>
  MINUSMINUS Expr@value <Decrl>
  Expr@value MINUSMINUS <Decrr>
  AMPERSAND Expr@value <Borrow>
  ASTERISK Expr@value <Deref>
  PLUS Expr@value <Plus>
  MINUS Expr@value <Minus>
  IDENT.0@value <Ident>
  SIZEOF LPAR Type@type RPAR <Sizeof>
  IDENT.0@name LPAR List[Expr, COMMA]@args RPAR <Call>
  Expr@array LBRACKET Expr@index RBRACKET <
    Deref
    value: Expr {
      BinOp
      op: AddSubOp { Add }
      left: array
      right: index
    }
  >
  (left-assoc) Expr@left MulDivModOp@op Expr@right <BinOp>
  (left-assoc) Expr@left AddSubOp@op Expr@right <BinOp>
  (left-assoc) Expr@left CmpOp@op Expr@right <BinOp>
  (left-assoc) Expr@left EqOp@op Expr@right <BinOp>
  (left-assoc) Expr@left AndOp@op Expr@right <BinOp>
  (left-assoc) Expr@left OrOp@op Expr@right <BinOp>
  (right-assoc) Expr@key EQUAL Expr@value <Assign>;

"an operator"
MulDivModOp ::=
  ASTERISK <Mul>
  SLASH <Div>
  PERCENT <Mod>;

"an operator"
AddSubOp ::=
  PLUS <Add>
  MINUS <Sub>;

"an operator"
CmpOp ::=
  LT <Lt>
  GT <Gt>
  GEQ <Geq>
  LEQ <Leq>;

"an operator"
EqOp ::=
  EQ <Equal>
  NEQ <NotEqual>;

"an operator"
AndOp ::=
  AND <And>;

"an operator"
OrOp ::=
  OR <Or>;

"a statement"
Statement ::=
  SEMICOLON <None>
  Expr@stmt SEMICOLON <Regular>
  IF LPAR Expr@condition RPAR Statement@then Option[Else]@else <If>
  WHILE LPAR Expr@condition RPAR Statement@body <While>
  FOR
    LPAR
      Option[VariableDeclaration]@init SEMICOLON
      Option[Expr]@test SEMICOLON
      List[Expr, COMMA]@step
    RPAR
    Statement@body <For>
  Block@stmts <Block>
  RETURN Option[Expr]@value SEMICOLON <Return>
  BREAK SEMICOLON <Break>
  CONTINUE SEMICOLON <Continue>;

Else ::=
  ELSE Statement@else <>;

"a block"
Block ::=
  LBRACE List[DeclStatement, Empty]@stmts RBRACE <>;

DeclStatement ::=
  FunctionDeclaration@declaration <Function>
  VariableDeclaration@declaration SEMICOLON <Declaration>
  Statement@stmt <Statement>;

"a variable declaration"
VariableDeclaration ::=
  Type@type IDENT.0@name Option[Definition]@value <>;

Definition ::=
  EQUAL Expr@value <>;