From 03e3c3f8071a70cab42316672ed8baa80b90137b Mon Sep 17 00:00:00 2001 From: LordBaryhobal Date: Fri, 6 Feb 2026 18:53:06 +0100 Subject: [PATCH] docs: add PEG BNF grammar --- docs/grammar.bnf | 105 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 docs/grammar.bnf diff --git a/docs/grammar.bnf b/docs/grammar.bnf new file mode 100644 index 0000000..75cd42e --- /dev/null +++ b/docs/grammar.bnf @@ -0,0 +1,105 @@ +{ + tokens=[ + SYM_UNDERSCORE="_" + + PUNC_LPAREN="(" + PUNC_RPAREN=")" + PUNC_LBRACE="{" + PUNC_RBRACE="}" + PUNC_COMMA="," + PUNC_DOT="." + PUNC_SEMICOLON=";" + PUNC_COLON=":" + + OP_PLUS="+" + OP_PLUS_EQUAL="+=" + OP_MINUS="-" + OP_MINUS_EQUAL="-=" + OP_SLASH="/" + OP_SLASH_EQUAL="/=" + OP_STAR="*" + OP_STAR_EQUAL="*=" + OP_EQUAL="=" + OP_EQUAL_EQUAL="==" + OP_BANG="!" + OP_BANG_EQUAL="!=" + OP_GREATER=">" + OP_GREATER_EQUAL=">=" + OP_LESS="<" + OP_LESS_EQUAL="<=" + + KW_LET="let" + KW_FUN="fun" + KW_AND="and" + KW_OR="or" + KW_IF="if" + KW_ELSE="else" + KW_FOR="for" + KW_WHILE="while" + KW_FROM="from" + KW_TO="to" + KW_UNTIL="until" + KW_BY="by" + KW_FALSE="false" + KW_TRUE="true" + KW_NULL="null" + KW_RETURN="return" + KW_BREAK="break" + KW_CONTINUE="continue" + + WHITE_SPACE="regexp:\s+" + + DIGIT="regexp:\d" + ALPHA="regexp:[a-zA-Z]" + STRING="regexp:('[^']*'|\"[^\"]*\")" + ] +} + +root ::= declaration* <> ; + +declaration ::= funDecl | varDecl | statement ; + +funDecl ::= KW_FUN function ; +varDecl ::= KW_LET IDENTIFIER ( OP_EQUAL expression )? ; + +statement ::= (exprStmt | forStmt | ifStmt | returnStmt | whileStmt | block | breakStmt | continueStmt) ; + +exprStmt ::= expression ; + +forStmt ::= KW_FOR IDENTIFIER forClauses? statement ; +forClauses ::= (fromClause) | (endClause) | (byClause) | (fromClause endClause) | (fromClause byClause) | (endClause fromClause) | (endClause byClause) | (byClause fromClause) | (byClause endClause) | (fromClause endClause byClause) | (fromClause byClause endClause) | (endClause fromClause byClause) | (endClause byClause fromClause) | (byClause fromClause endClause) | (byClause endClause fromClause) ; +fromClause ::= KW_FROM expression ; +endClause ::= toClause | untilClause ; +toClause ::= KW_TO expression ; +untilClause ::= KW_UNTIL expression ; +byClause ::= KW_BY expression ; + +ifStmt ::= KW_IF expression statement (KW_ELSE statement)? ; + +returnStmt ::= KW_RETURN expression? ; +whileStmt ::= KW_WHILE expression statement ; +block ::= PUNC_LBRACE declaration* PUNC_RBRACE ; +breakStmt ::= KW_BREAK ; +continueStmt ::= KW_CONTINUE ; + +expression ::= assignment ; + +assignment ::= IDENTIFIER OP_EQUAL assignment | logic_or ; + +logic_or ::= logic_and ( KW_OR logic_and )* ; +logic_and ::= equality ( KW_AND equality )* ; +equality ::= comparison ( ( OP_BANG_EQUAL | OP_EQUAL_EQUAL ) comparison )* ; +comparison ::= term ( ( OP_GREATER | OP_GREATER_EQUAL | OP_LESS | OP_LESS_EQUAL ) term )* ; +term ::= factor ( ( OP_MINUS | OP_PLUS ) factor )* ; +factor ::= unary ( ( OP_SLASH | OP_STAR ) unary )* ; + +unary ::= ( OP_BANG | OP_MINUS ) unary | call ; +call ::= primary ( PUNC_LPAREN arguments? PUNC_RPAREN )* ; +primary ::= KW_TRUE | KW_FALSE | KW_NULL | NUMBER | STRING | IDENTIFIER | PUNC_LPAREN expression PUNC_RPAREN ; + +function ::= IDENTIFIER PUNC_LPAREN parameters? PUNC_RPAREN block ; +parameters ::= IDENTIFIER ( PUNC_COMMA IDENTIFIER )* ; +arguments ::= expression ( PUNC_COMMA expression )* ; + +NUMBER ::= DIGIT+ ( PUNC_DOT DIGIT+ ) ?; +IDENTIFIER ::= ALPHA ( ALPHA | DIGIT | SYM_UNDERSCORE )* ;