diff --git a/debugger/Cargo.toml b/debugger/Cargo.toml index a557d13d..c2d4fc8d 100644 --- a/debugger/Cargo.toml +++ b/debugger/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "pest_debugger" description = "pest grammar debugger" -version = "2.5.3" +version = "2.5.4" edition = "2021" authors = ["Dragoș Tiselice ", "Tomas Tauber "] homepage = "https://pest.rs/" @@ -14,9 +14,9 @@ readme = "_README.md" rust-version = "1.56" [dependencies] -pest = { path = "../pest", version = "2.5.3" } -pest_meta = { path = "../meta", version = "2.5.3" } -pest_vm = { path = "../vm", version = "2.5.3" } +pest = { path = "../pest", version = "2.5.4" } +pest_meta = { path = "../meta", version = "2.5.4" } +pest_vm = { path = "../vm", version = "2.5.4" } rustyline = "10" thiserror = "1" diff --git a/derive/Cargo.toml b/derive/Cargo.toml index efc3f266..a7416a15 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "pest_derive" description = "pest's derive macro" -version = "2.5.3" +version = "2.5.4" edition = "2021" authors = ["Dragoș Tiselice "] homepage = "https://pest.rs/" @@ -23,5 +23,5 @@ std = ["pest/std", "pest_generator/std"] [dependencies] # for tests, included transitively anyway -pest = { path = "../pest", version = "2.5.3", default-features = false } -pest_generator = { path = "../generator", version = "2.5.3", default-features = false } +pest = { path = "../pest", version = "2.5.4", default-features = false } +pest_generator = { path = "../generator", version = "2.5.4", default-features = false } diff --git a/generator/Cargo.toml b/generator/Cargo.toml index a9645fc5..df4b4da8 100644 --- a/generator/Cargo.toml +++ b/generator/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "pest_generator" description = "pest code generator" -version = "2.5.3" +version = "2.5.4" edition = "2021" authors = ["Dragoș Tiselice "] homepage = "https://pest.rs/" @@ -18,8 +18,8 @@ default = ["std"] std = ["pest/std"] [dependencies] -pest = { path = "../pest", version = "2.5.3", default-features = false } -pest_meta = { path = "../meta", version = "2.5.3" } +pest = { path = "../pest", version = "2.5.4", default-features = false } +pest_meta = { path = "../meta", version = "2.5.4" } proc-macro2 = "1.0" quote = "1.0" syn = "1.0" diff --git a/grammars/Cargo.toml b/grammars/Cargo.toml index a7b802d6..03f1f5fb 100644 --- a/grammars/Cargo.toml +++ b/grammars/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "pest_grammars" description = "pest popular grammar implementations" -version = "2.5.3" +version = "2.5.4" edition = "2021" authors = ["Dragoș Tiselice "] homepage = "https://pest.rs/" @@ -14,8 +14,8 @@ readme = "_README.md" rust-version = "1.56" [dependencies] -pest = { path = "../pest", version = "2.5.3" } -pest_derive = { path = "../derive", version = "2.5.3" } +pest = { path = "../pest", version = "2.5.4" } +pest_derive = { path = "../derive", version = "2.5.4" } [dev-dependencies] criterion = "0.3" diff --git a/meta/Cargo.toml b/meta/Cargo.toml index 7a83d3b7..2ad3ec77 100644 --- a/meta/Cargo.toml +++ b/meta/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "pest_meta" description = "pest meta language parser and validator" -version = "2.5.3" +version = "2.5.4" edition = "2021" authors = ["Dragoș Tiselice "] homepage = "https://pest.rs/" @@ -16,7 +16,7 @@ include = ["Cargo.toml", "src/**/*", "src/grammar.rs", "_README.md", "LICENSE-*" rust-version = "1.56" [dependencies] -pest = { path = "../pest", version = "2.5.3" } +pest = { path = "../pest", version = "2.5.4" } once_cell = "1.8.0" [build-dependencies] diff --git a/meta/src/grammar.pest b/meta/src/grammar.pest index e09bf61b..fe618300 100644 --- a/meta/src/grammar.pest +++ b/meta/src/grammar.pest @@ -6,23 +6,34 @@ // license , at your // option. All files in the project carrying such notice may not be copied, // modified, or distributed except according to those terms. +//! Pest meta-grammar +/// The top-level rule of a grammar. grammar_rules = _{ SOI ~ grammar_doc* ~ (grammar_rule)+ ~ EOI } +/// A rule of a grammar. grammar_rule = { identifier ~ assignment_operator ~ modifier? ~ opening_brace ~ expression ~ closing_brace | line_doc } +/// Assignment operator. assignment_operator = { "=" } +/// Opening brace for a rule. opening_brace = { "{" } +/// Closing brace for a rule. closing_brace = { "}" } +/// Opening parenthesis for a branch, PUSH, etc. opening_paren = { "(" } +/// Closing parenthesis for a branch, PUSH, etc. closing_paren = { ")" } +/// Opening bracket for PEEK (slice inside). opening_brack = { "[" } +/// Closing bracket for PEEK (slice inside). closing_brack = { "]" } +/// A rule modifier. modifier = _{ silent_modifier | atomic_modifier | @@ -30,18 +41,29 @@ modifier = _{ non_atomic_modifier } +/// Silent rule prefix. silent_modifier = { "_" } +/// Atomic rule prefix. atomic_modifier = { "@" } +/// Compound atomic rule prefix. compound_atomic_modifier = { "$" } +/// Non-atomic rule prefix. non_atomic_modifier = { "!" } +/// A rule expression. expression = { choice_operator? ~ term ~ (infix_operator ~ term)* } +/// A rule term. term = { prefix_operator* ~ node ~ postfix_operator* } +/// A rule node (inside terms). node = _{ opening_paren ~ expression ~ closing_paren | terminal } +/// A terminal expression. terminal = _{ _push | peek_slice | identifier | string | insensitive_string | range } +/// Possible predicates for a rule. prefix_operator = _{ positive_predicate_operator | negative_predicate_operator } +/// Branches or sequences. infix_operator = _{ sequence_operator | choice_operator } +/// Possible modifiers for a rule. postfix_operator = _{ optional_operator | repeat_operator | @@ -52,55 +74,96 @@ postfix_operator = _{ repeat_min_max } +/// A positive predicate. positive_predicate_operator = { "&" } +/// A negative predicate. negative_predicate_operator = { "!" } +/// A sequence operator. sequence_operator = { "~" } +/// A choice operator. choice_operator = { "|" } +/// An optional operator. optional_operator = { "?" } +/// A repeat operator. repeat_operator = { "*" } +/// A repeat at least once operator. repeat_once_operator = { "+" } +/// A repeat exact times. repeat_exact = { opening_brace ~ number ~ closing_brace } +/// A repeat at least times. repeat_min = { opening_brace ~ number ~ comma ~ closing_brace } +/// A repeat at most times. repeat_max = { opening_brace ~ comma ~ number ~ closing_brace } +/// A repeat in a range. repeat_min_max = { opening_brace ~ number ~ comma ~ number ~ closing_brace } +/// A number. number = @{ '0'..'9'+ } +/// An integer number (positive or negative). integer = @{ number | "-" ~ "0"* ~ '1'..'9' ~ number? } +/// A comma terminal. comma = { "," } +/// A PUSH expression. _push = { "PUSH" ~ opening_paren ~ expression ~ closing_paren } +/// A PEEK expression. peek_slice = { "PEEK" ~ opening_brack ~ integer? ~ range_operator ~ integer? ~ closing_brack } +/// An identifier. identifier = @{ !"PUSH" ~ ("_" | alpha) ~ ("_" | alpha_num)* } +/// An alpha character. alpha = _{ 'a'..'z' | 'A'..'Z' } +/// An alphanumeric character. alpha_num = _{ alpha | '0'..'9' } +/// A string. string = ${ quote ~ inner_str ~ quote } +/// An insensitive string. insensitive_string = { "^" ~ string } +/// A character range. range = { character ~ range_operator ~ character } +/// A single quoted character character = ${ single_quote ~ inner_chr ~ single_quote } +/// A quoted string. inner_str = @{ (!("\"" | "\\") ~ ANY)* ~ (escape ~ inner_str)? } +/// An escaped or any character. inner_chr = @{ escape | ANY } +/// An escape sequence. escape = @{ "\\" ~ ("\"" | "\\" | "r" | "n" | "t" | "0" | "'" | code | unicode) } +/// A hexadecimal code. code = @{ "x" ~ hex_digit{2} } +/// A unicode code. unicode = @{ "u" ~ opening_brace ~ hex_digit{2, 6} ~ closing_brace } +/// A hexadecimal digit. hex_digit = @{ '0'..'9' | 'a'..'f' | 'A'..'F' } +/// A double quote. quote = { "\"" } +/// A single quote. single_quote = { "'" } +/// A range operator. range_operator = { ".." } +/// A newline character. newline = _{ "\n" | "\r\n" } +/// A whitespace character. WHITESPACE = _{ " " | "\t" | newline } +/// A single line comment. line_comment = _{ ("//" ~ !("/" | "!") ~ (!newline ~ ANY)*) } +/// A multi-line comment. block_comment = _{ "/*" ~ (block_comment | !"*/" ~ ANY)* ~ "*/" } +/// A grammar comment. COMMENT = _{ block_comment | line_comment } // ref: https://doc.rust-lang.org/reference/comments.html +/// A space character. space = _{ " " | "\t" } +/// A top-level comment. grammar_doc = ${ "//!" ~ space? ~ inner_doc } +/// A rule comment. line_doc = ${ "///" ~ space? ~ !"/" ~ inner_doc } +/// A comment content. inner_doc = @{ (!newline ~ ANY)* } diff --git a/pest/Cargo.toml b/pest/Cargo.toml index a9ddbefe..7ea229fc 100644 --- a/pest/Cargo.toml +++ b/pest/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "pest" description = "The Elegant Parser" -version = "2.5.3" +version = "2.5.4" edition = "2021" authors = ["Dragoș Tiselice "] homepage = "https://pest.rs/" diff --git a/vm/Cargo.toml b/vm/Cargo.toml index ecaab960..3be3db7c 100644 --- a/vm/Cargo.toml +++ b/vm/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "pest_vm" description = "pest grammar virtual machine" -version = "2.5.3" +version = "2.5.4" edition = "2021" authors = ["Dragoș Tiselice "] homepage = "https://pest.rs/" @@ -14,5 +14,5 @@ readme = "_README.md" rust-version = "1.56" [dependencies] -pest = { path = "../pest", version = "2.5.3" } -pest_meta = { path = "../meta", version = "2.5.3" } +pest = { path = "../pest", version = "2.5.4" } +pest_meta = { path = "../meta", version = "2.5.4" }