aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlow-It <Flow-It@users.noreply.github.com>2020-05-01 21:02:17 +0200
committerGitHub <noreply@github.com>2020-05-01 22:02:17 +0300
commita124624c0e18a44cd51e49d020b30393dbe8bc9d (patch)
tree06b719593cbef8e9f169c1c1204c7ae3974caebe
parentd7c24ccddd13b4b36d63df1908cfa886f9fb7324 (diff)
downloadmeson-a124624c0e18a44cd51e49d020b30393dbe8bc9d.zip
meson-a124624c0e18a44cd51e49d020b30393dbe8bc9d.tar.gz
meson-a124624c0e18a44cd51e49d020b30393dbe8bc9d.tar.bz2
Document formal Meson grammar [skip ci]
* WIP: Document formal Meson grammar * Various little fixes [skip ci] 1) Add missing logical_not_expr 2) 'in' and 'not in' are valid relational operators at least for dicts 3) dictionary keys can be expressions, but kwarg names cannot 4) typo logical_end_expression -> logical_and_expression 5) Make jump statements only allowed inside an iteration statement * Rework EBNF style [skip ci] As there is no good order for the productions, just go alphabetically. The EBNF style was changed to match the one the Python lark project uses, that is colons for productions and terminals enclosed in double quotes. * Add missing production for unary operators [skip ci] * Add production for multiline strings [skip ci] * Properly define terminal symbols [skip ci] Depending on the EBNF flavor, regex can be used to describe the terminal symbols. Lark allows this, and as it was mentioned as a possible user of this grammar, let's follow its flavor here. Most regexes used are easily human-readable, and we can always add comments to more complicated ones. * Small changes to which expressions can be used where [skip ci] Let the grammar be very general. The type system then has to check, that the used expression really evaluates to the correct type. Even if we know today that assignment expressions always evaluate to None (and can therefore only be used as a toplevel expression in an expression statement), this needn't be the case forever. So this way, the grammar stays stable even if such changes were made. * Rework function argument list production [skip ci] * Be more verbose for production names [skip ci] Rename expr -> expression, stmt -> statement, op -> operator, program -> build_definition. Also adjust some list productions. * Add paragraph about syntax stability promises [skip ci]
-rw-r--r--docs/markdown/Syntax.md70
1 files changed, 70 insertions, 0 deletions
diff --git a/docs/markdown/Syntax.md b/docs/markdown/Syntax.md
index cf0516c..666d50e 100644
--- a/docs/markdown/Syntax.md
+++ b/docs/markdown/Syntax.md
@@ -588,3 +588,73 @@ FAQ](FAQ.md#why-is-meson-not-just-a-python-module-so-i-could-code-my-build-setup
because of this limitation you find yourself copying and pasting code
a lot you may be able to use a [`foreach` loop
instead](#foreach-statements).
+
+Stability Promises
+--
+
+Meson is very actively developed and continuously improved. There is a
+possibility that future enhancements to the Meson build system will require
+changes to the syntax. Such changes might be the addition of new reserved
+keywords, changing the meaning of existing keywords or additions around the
+basic building blocks like statements and fundamental types. It is planned
+to stabilize the syntax with the 1.0 release.
+
+Grammar
+--
+
+This is the full Meson grammar, as it is used to parse Meson build definition files:
+
+```
+additive_expression: multiplicative_expression | (additive_expression additive_operator multiplicative_expression)
+additive_operator: "+" | "-"
+argument_list: positional_arguments ["," keyword_arguments] | keyword_arguments
+array_literal: "[" [expression_list] "]"
+assignment_expression: conditional_expression | (logical_or_expression assignment_operator assignment_expression)
+assignment_operator: "=" | "*=" | "/=" | "%=" | "+=" | "-="
+boolean_literal: "true" | "false"
+build_definition: (NEWLINE | statement)*
+condition: expression
+conditional_expression: logical_or_expression | (logical_or_expression "?" expression ":" assignment_expression
+decimal_literal: DECIMAL_NUMBER
+DECIMAL_NUMBER: /[1-9][0-9]*/
+dictionary_literal: "{" [key_value_list] "}"
+equality_expression: relational_expression | (equality_expression equality_operator relational_expression)
+equality_operator: "==" | "!="
+expression: assignment_expression
+expression_list: expression ("," expression)*
+expression_statememt: expression
+function_expression: id_expression "(" [argument_list] ")"
+hex_literal: "0x" HEX_NUMBER
+HEX_NUMBER: /[a-fA-F0-9]+/
+id_expression: IDENTIFIER
+IDENTIFIER: /[a-zA-Z_][a-zA-Z_0-9]*/
+identifier_list: id_expression ("," id_expression)*
+integer_literal: decimal_literal | octal_literal | hex_literal
+iteration_statement: "foreach" identifier_list ":" id_expression NEWLINE (statement | jump_statement)* "endforeach"
+jump_statement: ("break" | "continue") NEWLINE
+key_value_item: expression ":" expression
+key_value_list: key_value_item ("," key_value_item)*
+keyword_item: id_expression ":" expression
+keyword_arguments: keyword_item ("," keyword_item)*
+literal: integer_literal | string_literal | boolean_literal | array_literal | dictionary_literal
+logical_and_expression: equality_expression | (logical_and_expression "and" equality_expression)
+logical_or_expression: logical_and_expression | (logical_or_expression "or" logical_and_expression)
+method_expression: postfix_expression "." function_expression
+multiplicative_expression: unary_expression | (multiplicative_expression multiplicative_operator unary_expression)
+multiplicative_operator: "*" | "/" | "%"
+octal_literal: "0o" OCTAL_NUMBER
+OCTAL_NUMBER: /[0-7]+/
+positional_arguments: expression ("," expression)*
+postfix_expression: primary_expression | subscript_expression | function_expression | method_expression
+primary_expression: literal | ("(" expression ")") | id_expression
+relational_expression: additive_expression | (relational_expression relational_operator additive_expression)
+relational_operator: ">" | "<" | ">=" | "<=" | "in" | ("not" "in")
+selection_statement: "if" condition NEWLINE (statement)* ("elif" condition NEWLINE (statement)*)* ["else" (statement)*] "endif"
+statement: (expression_statement | selection_statement | iteration_statement) NEWLINE
+string_literal: ("'" STRING_SIMPLE_VALUE "'") | ("'''" STRING_MULTILINE_VALUE "'''")
+STRING_MULTILINE_VALUE: \.*?(''')\
+STRING_SIMPLE_VALUE: \.*?(?<!\\)(\\\\)*?'\
+subscript_expression: postfix_expression "[" expression "]"
+unary_expression: postfix_expression | (unary_operator unary_expression)
+unary_operator: "not" | "+" | "-"
+```