/LoxLang

Rust implementation of the Lox lang

Primary LanguageRust

Rust implementation of the Lox lang

Grammar

program = declaration * EOF;


declaration =  classDecl
              | funDecl
              | varDecl
              | statement;

classDecl =  "class" IDENTIFIER ( "<" IDENTIFIER ) ?
             "{" function* "}";

funDecl   = "fun" function ;
varDecl   = "var" IDENTIFIER ( "=" expression )? ";";
statement = exprStmt
            | forStmt
            | ifStmt
            | printStmt
            | returnStmt
            | whileStmt
            | block;

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

ifStmt     = "if" "("    expression ")" statement ( "else" statement)?;
printStmt  = "print"     expression ";" ;
returnStmt = "return"    expression? ";" ;
whileStmt  = "while" "(" expression ")"  statement;
block      = "{" declaration* "}";


expression     = assignment ;

assignment     = ( call "." )? IDENTIFIER "=" assignment
               | logic_or;

logic_or       = logic_and ( "or" logic_and )* ;
logic_and      = equality ( "and" equality )* ;
equality       = comparison ( ( "!=" | "==" ) comparison )* ;
comparison     = addition ( ( ">" | ">=" | "<" | "<=" ) addition )* ;
addition       = multiplication ( ( "-" | "+" ) multiplication )* ;
multiplication = unary ( ( "/" | "*" ) unary )* ;

unary          = ( "!" | "-" ) unary | call ;
call           = primary ( "(" arguments? ")" | "." IDENTIFIER )* ;
primary        = "true" | "false" | "nil" | "this"
               | NUMBER | STRING | IDENTIFIER | "(" expression ")"
               | "super" "." IDENTIFIER ;

unction      = IDENTIFIER "(" parameters? ")" block ;
parameters   = IDENTIFIER ( "," IDENTIFIER )* ;
arguments    = expression ( "," expression )* ;


NUMBER        = DIGIT+ ( "." DIGIT+ )? ;
STRING        = '"' <any char except '"'>* '"' ;
IDENTIFIER    = ALPHA ( ALPHA | DIGIT )* ;
ALPHA         = 'a' ... 'z' | 'A' ... 'Z' | '_' ;
DIGIT         = '0' ... '9' ;