// when blog is done https://cookeylangblog.cookeylangteam.repl.co

grammar

Setup

There are a few things will have to be defined before the grammar.

parameters => IDENTIFIER ( "," IDENTIFIER )*
parameterexpressions => expression ( "," expression )*
arguments => expression ( "," expression )*

IDENTIFIER = [ a-z A-Z _ ] ( [ a-z A-Z _ 0-9 ] )*
NUMBER = [ 0-9 ] ( "." [ 0-9 ]+ )?
STRING = ( "\"" ANY "\"" | "'" ANY "'" )

Program

The program consists of one or more declaration, the operator with the lowest precedence

program => declaration* EOF

Variable Declaration

There are 3 ways to declare variables.

declaration => classDecl | funcDecl | varDecl | statement

Classes.

classDecl => "class" IDENTIFIER ( "extends" IDENTIFIER )? "{" function* "}"

Functions.

funcDecl => "function" function
function => IDENTIFIER "(" parameters? ")" block

Variables.

varDecl => ( "var" | "final" ) IDENTIFIER ( "=" expression? ) ";"

Program

Statements have lower precendence.

statement => exprStmt | ifStmt | exitStmt | whileStmt | returnStmt | breakStmt | forStmt | switchStmt | doWhileStmt | forRepStmt | deleteVarStmt | block

Expressions.

exprStmt => expression ";"

If statements.

ifStmt => "if" "(" expression ")" statement ( "else" statement )?

Exit.

exitStmt => "exit" expression? ";"

While Loops.

whileStmt => "while" "(" expression ")" statement

For Loops.

forStmt => "for" "(" ( varDecl | exprStmt | ";" ) expression? ";" expression? ")" statement

Return Statements.

returnStmt => "return" expression? ";"

Break.

breakStmt => "break" ";"

Switch Statements.

switchStmt => "switch" "(" expression ")" "{" switchCaseFunc* defaultCaseFunc? "}"

switchCaseFunc => "case" "(" parameterexpressions ")" statement
defaultCaseFunc => "default" statement

Do While Loops.

doWhileStmt => "do" statement "while" "(" expression ")" ";"

Forrep Loops.

forRepStmt => "forrep" "(" parameterexpressions ")" statement

Delete Variable.

deleteVarStmt => "deletevariable" IDENTIFIER ";"

Block.

block => "{" declaration* "}"

Expression

Expressions are lambdas or ternary statements.

expression => ( "lambda" "(" parameters? ")" ":" )? ternary

Ternary

Ternary statements wrap around postfix.

ternary => postfix ( "?" postfix ":" ternary )?

Assignment

Postfix wraps arounds assignment.

postfix => assignment ( "++" | "--" )?

Assignments are equal precendence as logic or.

assignment => ( ( call "." )? IDENTIFIER ( "+=" | "-=" | "*=" | "/=" | "^=" | "%=" ) assignment ) | logic_or

Logic

Or statements have lower precedence than and statements.

logic_or => logic_and ( "or" logic_and )*
logic_and => equality ( "and" equality )*

Equality has lower precedence than comparison.

equality => comparison ( ( "!=" | "==" ) comparison )*
comparison => addition ( ( ">" | ">=" | "<" | "<=" ) addition )*

Math

Addition has lower precedence than multiplication.

addition => multiplication ( ( "-" | "+" ) multiplication )*
multiplication => power ( ( "/" | "*" | "%" ) power )*

Power statements have higher precendence than multiplication.

power => unary ( "^" unary )*

Unary

Unary comes before type-change. Note that +1 is not an unary statement.

unary => ( ( "!" | "-" ) unary ) | type_change

Type changes have higher precedence so -@"number":"3" does not require parentheses.

type_change => ( "@" STRING ":" type_change )? call

Functions

Functions have higher precedence than type-change statements.

call => primary ( ( "(" arguments? ")" )* | "." IDENTIFIER )

Primary

Primary statements have the highest precedence.

primary => NUMBER | STRING | IDENTIFIER | "false" | "true" | "this" | "NaV" | "(" expression ")" | "|" expression "|" | "superClass" "." IDENTIFIER