|
1 | 1 | # Lua syntax |
2 | 2 |
|
3 | | -Complete Lua syntax in [extended BNF][extended bnf], as in it’s |
4 | | -[own manual][lua manual]. |
| 3 | +Complete Lua syntax in [extended BNF][extended bnf], adapted from it’s |
| 4 | +[manual][lua manual]. |
5 | 5 |
|
6 | 6 | ```ebnf |
7 | | -chunk ::= |
8 | | - block |
| 7 | +chunk = [block]; |
9 | 8 |
|
10 | | -block ::= |
11 | | - {stat} [retstat] |
| 9 | +block = return_statement | statement {statement} [return_statement]; |
12 | 10 |
|
13 | | -stat ::= |
14 | | - ';' | varlist '=' explist | functioncall | label | break | goto Name | |
15 | | - do block end | |
16 | | - while exp do block end | |
17 | | - repeat block until exp | |
18 | | - if exp then block {elseif exp then block} [else block] end | |
19 | | - for Name '=' exp ',' exp [',' exp] do block end | |
20 | | - for namelist in explist do block end | |
21 | | - function funcname funcbody | |
22 | | - local function Name funcbody | |
23 | | - local namelist ['=' explist] |
| 11 | +(* statements *) |
| 12 | +return_statement = "return" [expression_list] [empty_statement]; |
24 | 13 |
|
25 | | -retstat ::= |
26 | | - return [explist] [';'] |
| 14 | +statement = do_statement | if_statement | for_numeric_statement |
| 15 | + | for_generic_statement | while_statement | repeat_statement | break_statement |
| 16 | + | label_statement | goto_statement | variable_assignment |
| 17 | + | scoped_variable_declaration | function_declaration | scoped_function_declaration |
| 18 | + | function_call | empty_statement; |
27 | 19 |
|
28 | | -label ::= |
29 | | - '::' Name '::' |
| 20 | +empty_statement = ";"; |
30 | 21 |
|
31 | | -funcname ::= |
32 | | - Name {'.' Name} [':' Name] |
| 22 | +scoped_function_declaration = "local" "function" identifier function_body; |
33 | 23 |
|
34 | | -varlist ::= |
35 | | - var {, var} |
| 24 | +function_declaration = "function" function_identifier function_body; |
| 25 | +function_identifier = identifier {"." identifier} [":" identifier]; |
36 | 26 |
|
37 | | -var ::= |
38 | | - Name | prefixexp '[' exp ']' | prefixexp '.' Name |
| 27 | +scoped_variable_declaration = "local" identifier_list ["=" expression_list]; |
39 | 28 |
|
40 | | -namelist ::= |
41 | | - Name {',' Name} |
| 29 | +variable_assignment = variable_list "=" expression_list; |
| 30 | +variable_list = variable {"," variable}; |
42 | 31 |
|
43 | | -explist ::= |
44 | | - exp {',' exp} |
| 32 | +goto_statement = "goto" identifier; |
| 33 | +label_statement = "::" identifier "::"; |
45 | 34 |
|
46 | | -exp ::= |
47 | | - nil | false | true | Numeral | LiteralString | '...' | functiondef | |
48 | | - prefixexp | tableconstructor | exp binop exp | unop exp |
| 35 | +break_statement = "break"; |
| 36 | +repeat_statement = "repeat" [block] "until" expression; |
| 37 | +while_statement = "while" expression "do" [block] "end"; |
| 38 | +for_generic_statement = "for" identifier_list "in" expression_list |
| 39 | + "do" [block] "end"; |
| 40 | +for_numeric_statement = "for" identifier "=" expression "," expression ["," expression] |
| 41 | + "do" [block] "end"; |
49 | 42 |
|
50 | | -prefixexp ::= |
51 | | - var | functioncall | '(' exp ')' |
| 43 | +if_statement = "if" expression "then" [block] {"elseif" expression "then" [block]} |
| 44 | + ["else" [block]] "end"; |
52 | 45 |
|
53 | | -functioncall ::= |
54 | | - prefixexp args | prefixexp ':' Name args |
| 46 | +do_statement = "do" [block] "end"; |
55 | 47 |
|
56 | | -args ::= |
57 | | - '(' [explist] ')' | tableconstructor | LiteralString |
| 48 | +(* expressions *) |
| 49 | +expression = nil | boolean | number | string | unary_expression |
| 50 | + | binary_expression | table | vararg_expression | function_definition |
| 51 | + | prefix_expression; |
58 | 52 |
|
59 | | -functiondef ::= |
60 | | - function funcbody |
| 53 | +prefix_expression = variable | function_call | "(" expression ")"; |
| 54 | +variable = identifier | prefix_expression "." identifier |
| 55 | + | prefix_expression "[" expression "]"; |
| 56 | +function_call = prefix_expression [":" identifier] argument_list; |
| 57 | +argument_list = string | table | "(" [expression_list] ")"; |
| 58 | +expression_list = expression {"," expression}; |
61 | 59 |
|
62 | | -funcbody ::= |
63 | | - '(' [parlist] ')' block end |
| 60 | +function_definition = "function" function_body; |
| 61 | +function_body = "(" [parameter_list] ")" [block] "end"; |
| 62 | +parameter_list = vararg_expression | identifier_list ["," vararg_expression]; |
| 63 | +identifier_list = identifier {"," identifier}; |
64 | 64 |
|
65 | | -parlist ::= |
66 | | - namelist [',' '...'] | '...' |
| 65 | +vararg_expression = "..."; |
67 | 66 |
|
68 | | -tableconstructor ::= |
69 | | - '{' [ fieldlist ] '}' |
| 67 | +table = "{" [field_list] "}"; |
| 68 | +field_list = field {field_separator field} [field_separator]; |
| 69 | +field = expression | identifier "=" expression | "[" expression "]" "=" expression; |
| 70 | +field_separator = "," | ";"; |
70 | 71 |
|
71 | | -fieldlist ::= |
72 | | - field {fieldsep field} [fieldsep] |
| 72 | +binary_expression = expression binary_operator expression; |
| 73 | +binary_operator = "or" | "and" | "==" | "~=" | "<" | ">" | "<=" | ">=" | "|" |
| 74 | + | "~" | "&" | "<<" | ">>" | ".." | "+" | "-" | "*" | "/" | "//" | "%" | "^"; |
73 | 75 |
|
74 | | -field ::= |
75 | | - '[' exp ']' '=' exp | Name '=' exp | exp |
| 76 | +unary_expression = unary_operator expression; |
| 77 | +unary_operator = "not" | "#" | "-" | "~"; |
76 | 78 |
|
77 | | -fieldsep ::= |
78 | | - ',' | ';' |
| 79 | +string = "'" {, inline_character - "'"}, "'" |
| 80 | + | '"' {, inline_character - '"'}, '"' |
| 81 | + | multiline_start {, character}, multiline_end; |
| 82 | +inline_character = ? any character except a newline ?; |
| 83 | +character = ? any character ?; |
79 | 84 |
|
80 | | -binop ::= |
81 | | - '+' | '-' | '*' | '/' | '//' | '^' | '%' | |
82 | | - '&' | '~' | '|' | '>>' | '<<' | '..' | |
83 | | - '<' | '<=' | '>' | '>=' | '==' | '~=' | |
84 | | - not | or |
| 85 | +number = decimal | hexadecimal; |
85 | 86 |
|
86 | | -unop ::= |
87 | | - '-' | not | '#' | '~' |
| 87 | +hexadecimal = ["-"] ("0x" | "0X"), hexadecimal_numeral [, ("p" | "P"), exponent]; |
| 88 | +hexadecimal_numeral = hexadecimal_digit {, hexadecimal_digit} |
| 89 | + | hexadecimal_digit {, hexadecimal_digit}, "." {, hexadecimal_digit} |
| 90 | + | {hexadecimal_digit ,} ".", hexadecimal_digit {, hexadecimal_digit}; |
| 91 | +hexadecimal_digit = ? hexadecimal numeric character ?; |
| 92 | +
|
| 93 | +decimal = ["-"] decimal_numeral [, ("e" | "E"), exponent]; |
| 94 | +decimal_numeral = decimal_digit {, decimal_digit} |
| 95 | + | decimal_digit {, decimal_digit}, "." {, decimal_digit} |
| 96 | + | {decimal_digit ,} ".", decimal_digit {, decimal_digit}; |
| 97 | +decimal_digit = ? decimal numeric character ?; |
| 98 | +
|
| 99 | +exponent = [("+" | "-") ,] decimal_digit {, decimal_digit}; |
| 100 | +
|
| 101 | +boolean = "false" | "true"; |
| 102 | +
|
| 103 | +nil = "nil"; |
| 104 | +
|
| 105 | +identifier = (letter | "_") {, letter | decimal_digit | "_"}; |
| 106 | +letter = ? case insensitive alphabetic character ?; |
| 107 | +
|
| 108 | +(* extras *) |
| 109 | +comment = "--" {, inline_character} |
| 110 | + | "--", multiline_start {, character}, multiline_end; |
| 111 | +
|
| 112 | +(* "start" and "end" must have the same number of equal signs ("=") *) |
| 113 | +multiline_start = "[" {, "="}, "["; |
| 114 | +multiline_end = "]" {, "="}, "]"; |
88 | 115 | ``` |
89 | 116 |
|
90 | 117 | [extended bnf]: https://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_form |
|
0 commit comments