ssc/ssc/sunscript.grammar
2016-02-22 21:04:13 -05:00

206 lines
6 KiB
Text

%header%
GRAMMARTYPE = "LL"
%tokens%
// whitespace
WHITESPACE = <<[ \t\r\n]+>> %ignore%
// comments
SINGLE_LINE_COMMENT = <<//.*>> %ignore%
MULTI_LINE_COMMENT = <</\*([^*]|\*+[^*/])*\*+/>> %ignore%
// keywords
IMPORT = "import"
BUILTIN = "builtin"
FUNCTION = "function"
VAR = "var"
LOCAL = "local"
CONST = "const"
IF = "if"
ELSE = "else"
DO = "do"
WHILE = "while"
FOR = "for"
RETURN = "return"
BREAK = "break"
CONTINUE = "continue"
YIELD = "yield"
EXIT = "exit"
LOCK = "lock"
UNLOCK = "unlock"
TRUE = "true"
FALSE = "false"
// punctuation
L_BRACE = "{"
R_BRACE = "}"
L_PAREN = "("
R_PAREN = ")"
L_BRACKET = "["
R_BRACKET = "]"
COLON = ":"
SEMICOLON = ";"
COMMA = ","
DOT = "."
ELLIPSIS = "..."
QMARK = "?"
// operators
ADD = "+"
SUB = "-" // doubles as the negation operator
MUL = "*"
DIV = "/"
MOD = "%"
BAND = "&"
BOR = "|"
LSH = "<<"
RSH = ">>"
NOT = "!"
AND = "&&"
OR = "||"
EQ = "=="
NE = "!="
LT = "<"
LE = "<="
GT = ">"
GE = ">="
ASSIGN = "="
ASSIGN_ADD = "+="
ASSIGN_SUB = "-="
ASSIGN_MUL = "*="
ASSIGN_DIV = "/="
ASSIGN_MOD = "%="
ASSIGN_BAND = "&="
ASSIGN_BOR = "|="
ASSIGN_LSH = "<<="
ASSIGN_RSH = ">>="
INCREMENT = "++"
DECREMENT = "--"
// literals
IDENTIFIER = <<[_A-Za-z][_A-Za-z0-9]*>>
FLOAT_LITERAL = <<-?[0-9]+\.[0-9]+>>
HEX_LITERAL = <<-?0x[0-9A-Fa-f]+>>
INTEGER_LITERAL = <<-?[0-9]+>>
ADDRESS_LITERAL = <<\$[0-9A-Fa-f]{8}>>
STRING_LITERAL = <<"(\\.|[^"])*">>
%productions%
script = root_statement+;
// statements
root_statement =
import_statement SEMICOLON |
function_definition |
builtin_declaration SEMICOLON |
statement;
statement =
compound_statement SEMICOLON |
if_statement |
name_label |
while_statement |
do_statement SEMICOLON |
for_statement |
return_statement SEMICOLON |
break_statement SEMICOLON |
continue_statement SEMICOLON |
yield_statement SEMICOLON |
exit_statement SEMICOLON |
lock_statement SEMICOLON |
unlock_statement SEMICOLON |
statement_block;
compound_statement = compound_statement_item {COMMA compound_statement_item};
compound_statement_item =
variable_definition |
variable_declaration |
variable_assignment |
variable_augment |
function_call;
statement_block = L_BRACE {statement} R_BRACE;
import_statement = IMPORT STRING_LITERAL;
yield_statement = YIELD;
exit_statement = EXIT;
lock_statement = LOCK;
unlock_statement = UNLOCK;
name_label = IDENTIFIER COLON;
// operators
assignment_operator = ASSIGN | ASSIGN_ADD | ASSIGN_SUB | ASSIGN_MUL | ASSIGN_DIV | ASSIGN_MOD | ASSIGN_BAND | ASSIGN_BOR | ASSIGN_LSH | ASSIGN_RSH;
ternary_operator = expression QMARK expression COLON expression;
binary_operator =
ADD | SUB | MUL | DIV | MOD | // arithmetic
BAND | BOR | LSH | RSH | // bitwise
EQ | NE | LT | LE | GT | GE | // comparison
AND | OR; // logical
unary_operator = NOT | SUB;
augment_operator = INCREMENT | DECREMENT;
// expressions
expression = operand {binary_operator operand};
operand = [unary_operator_list] term;
term =
function_call |
variable_reference |
variable_augment |
STRING_LITERAL |
FLOAT_LITERAL |
ADDRESS_LITERAL |
HEX_LITERAL |
INTEGER_LITERAL |
TRUE |
FALSE |
L_PAREN expression R_PAREN |
L_BRACKET ternary_operator R_BRACKET; // HACK: the brackets remove ambiguity
unary_operator_list = unary_operator+;
// variables
variable_reference = IDENTIFIER; // used in expressions
variable_declaration = variable_modifiers IDENTIFIER;
variable_definition = variable_modifiers IDENTIFIER ASSIGN expression;
variable_modifiers = VAR [LOCAL] [CONST];
variable_assignment = IDENTIFIER assignment_operator expression;
variable_augment = postfix_augment | prefix_augment;
postfix_augment = IDENTIFIER augment_operator;
prefix_augment = augment_operator IDENTIFIER;
// functions
function_definition = function_modifiers IDENTIFIER parameter_list statement_block;
function_modifiers = FUNCTION [LOCAL] [CONST];
function_call = IDENTIFIER argument_list;
parameter_list = L_PAREN [IDENTIFIER {COMMA IDENTIFIER} [COMMA ELLIPSIS] | ELLIPSIS] R_PAREN; // e.g. (a, b, ...)
argument_list = L_PAREN [expression {COMMA expression}] R_PAREN;
// builtins
builtin_declaration = builtin_modifiers IDENTIFIER parameter_list;
builtin_modifiers = BUILTIN [CONST];
// flow control
if_statement = IF L_PAREN expression R_PAREN statement [ELSE statement];
while_statement = WHILE L_PAREN expression R_PAREN statement;
do_statement = DO statement WHILE L_PAREN expression R_PAREN;
for_statement = FOR L_PAREN [for_declaration] SEMICOLON [for_condition] SEMICOLON [for_iteration] R_PAREN statement;
for_declaration = compound_statement;
for_condition = expression;
for_iteration = compound_statement;
return_statement = RETURN [expression];
break_statement = BREAK [IDENTIFIER];
continue_statement = CONTINUE [IDENTIFIER];