(* -- Grammar for Roost v2 -- Author: RubixDev *) Program = Statements ; (* The end of is indicated by a following `Eof` or `RBrace` token *) Statements = [ Statement , { EOL , Statement } , [ EOL ] ] ; Block = BlockExpr | Statement ; (**************************) (******* STATEMENTS *******) (**************************) Statement = VarStmt | FunctionDecl | ClassDecl | BreakStmt | ContinueStmt | ReturnStmt | Expression ; VarStmt = 'var' , identifier , [ '=' , Expression ] ; FunctionDecl = 'fun' , identifier , Params , Block ; ClassDecl = 'class' , identifier , MemberBlock ; BreakStmt = 'break' , [ Expression ] ; ContinueStmt = 'continue' ; ReturnStmt = 'return' , [ Expression ] ; (*****************************) (******* CLASS MEMBERS *******) (*****************************) Member = [ 'static' ] , ( FunctionDecl | VarStmt ) ; MemberBlock = '{' , { Member , EOL } , '}' ; (***************************) (******* EXPRESSIONS *******) (***************************) Expression = RangeExpr ; RangeExpr = OrExpr | OrExpr , ( '..' | '..=' ) , OrExpr | OrExpr , '..' | ( '..' | '..=' ) , OrExpr | '..' ; OrExpr = AndExpr , { '||' , AndExpr } ; AndExpr = BitOrExpr , { '&&' , BitOrExpr } ; BitOrExpr = BitXorExpr , { '|' , BitXorExpr } ; BitXorExpr = BitAndExpr , { '^' , BitAndExpr } ; BitAndExpr = EqExpr , { '&' , EqExpr } ; EqExpr = RelExpr , [ ( '==' | '!=' ) , RelExpr ] ; RelExpr = ShiftExpr , [ ( '<' | '>' | '<=' | '>=' ) , ShiftExpr ] ; ShiftExpr = AddExpr , { ( '<<' | '>>' ) , AddExpr } ; AddExpr = MulExpr , { ( '+' | '-' ) , MulExpr } ; MulExpr = UnaryExpr , { ( '*' | '/' | '%' | '\' ) , UnaryExpr } ; UnaryExpr = ( '+' | '-' | '!' ) , UnaryExpr | ExpExpr ; ExpExpr = AssignExpr , [ '**' , UnaryExpr ] ; AssignExpr = CallExpr , [ ASSIGN_OPERATOR , Expression ] ; ASSING_OPERATOR = '=' | '*=' | '/=' | '\=' | '%=' | '+=' | '-=' | '<<=' | '>>=' | '&=' | '^=' | '|=' | '**=' ; CallExpr = MemberExpr , [ Args , { CallPart } ] ; MemberExpr = Atom , { MemberPart } ; Atom = number | bool | string | 'null' | identifier | '(' , Expression , ')' | ListLiteral | IfExpr | ForExpr | WhileExpr | LoopExpr | FunExpr | ClassExpr | TryExpr | BlockExpr ; ListLiteral = '[' , [ Expression , { ',' , Expression } , [ ',' ] ] , ']' ; IfExpr = 'if' , '(' , Expression , ')' , Block , [ 'else' , Block ] ; ForExpr = 'for' , '(' , identifier , 'in' , Expression , ')' , Block ; WhileExpr = 'while' , '(' , Expression , ')' , Block ; LoopExpr = 'loop' , Block ; FunExpr = 'fun' , Params , Block ; ClassExpr = 'class' , MemberBlock ; TryExpr = 'try' , Block , 'catch' , '(' , identifier , ')' , Block ; BlockExpr = '{' , Statements , '}' ; (*********************) (******* OTHER *******) (*********************) MemberPart = '.' , identifier | '[' , Expression , ']' ; CallPart = MemberPart | Args ; Args = '(' , [ Expression , { ',' , Expression } , [ ',' ] ] , ')' ; Params = '(' , [ identifier , { ',' , identifier } , [ ',' ] ] , ')' ; (**********************************) (******* NONTERMINAL TOKENS *******) (**********************************) number = DIGIT , { DIGIT | '_' } , [ '.' , DIGIT , { DIGIT | '_' } ] | '.' , DIGIT , { DIGIT , | '_' } ; string = '"' , { CHAR - ( '"' | '\' ) | escape_seq } , '"' | "'" , { CHAR - ( "'" | '\' ) | escape_seq } , "'" ; escape_seq = '\' , ( ESCAPE_CHAR | 3 * OCTAL | 'x' , 2 * HEX | 'u' , 4 * HEX | 'U' , 8 * HEX ) ; bool = 'true' | 'false' ; identifier = ( LETTER , { LETTER | DIGIT } ) - ( bool | 'null' | ? any keyword ? ) ; (************************************) (******* TERMINAL SYMBOL SETS *******) (************************************) LETTER = 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z' | 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z' | '_' ; OCTAL = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' ; DIGIT = OCTAL | '8' | '9' ; HEX = DIGIT | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'a' | 'b' | 'c' | 'd' | 'e' | 'f' ; CHAR = ? any character included in the Unicode character set ? ; ESCAPE_CHAR = '\' | "'" | '"' | 'a' | 'b' | 'f' | 'n' | 'r' | 't' | 'v' ; (* : End Of Line Note: Line break characters (LF) are treated like spaces throughout the parsing process but, unlike the other space characters (' ', '\t', and '\r'), are accepted in place of semicolons. *) EOL = ';' | ? line feed ? ;