diff --git a/parser/src/parser/cst2ast.rs b/parser/src/parser/cst2ast.rs index 7045e709e..6e0d1e0b7 100644 --- a/parser/src/parser/cst2ast.rs +++ b/parser/src/parser/cst2ast.rs @@ -1774,6 +1774,9 @@ where let mut literal = integer_lit.as_str(); let mut multiplier = 1; + let without_underscore = literal.replace('_', ""); + literal = without_underscore.as_str(); + if let Some(without_suffix) = literal.strip_suffix("KB") { literal = without_suffix; multiplier = 1024; @@ -1833,9 +1836,12 @@ fn float_lit_from_cst<'src>( ) -> Result { expect!(float_lit, GrammarRule::float_lit); - let literal = float_lit.as_str(); + let mut literal = float_lit.as_str(); let span = ctx.span(&float_lit); + let without_underscore = literal.replace('_', ""); + literal = without_underscore.as_str(); + literal.parse::().map_err(|err| { Error::from(ErrorInfo::invalid_float( ctx.report_builder, diff --git a/parser/src/parser/grammar.pest b/parser/src/parser/grammar.pest index 7141e5e2b..142cf0353 100644 --- a/parser/src/parser/grammar.pest +++ b/parser/src/parser/grammar.pest @@ -277,13 +277,13 @@ string_lit = @{ } integer_lit = @{ - "-"? ~ "0x" ~ ASCII_HEX_DIGIT+ | - "-"? ~ "0o" ~ ASCII_OCT_DIGIT+ | - "-"? ~ ASCII_DIGIT+ ~ ("KB" | "MB")? + "-"? ~ "0x" ~ ASCII_HEX_DIGIT+ ~ ("_" | ASCII_HEX_DIGIT)* | + "-"? ~ "0o" ~ ASCII_OCT_DIGIT+ ~ ("_" | ASCII_OCT_DIGIT)* | + "-"? ~ ASCII_DIGIT+ ~ ("_" | ASCII_DIGIT)* ~ ("KB" | "MB")? } float_lit = @{ - "-"? ~ ASCII_DIGIT+ ~ DOT ~ ASCII_DIGIT+ + "-"? ~ ASCII_DIGIT+ ~ ("_" | ASCII_DIGIT)* ~ DOT ~ ASCII_DIGIT+ ~ ("_" | ASCII_DIGIT)* } regexp = @{ diff --git a/parser/src/parser/tests/cst.rs b/parser/src/parser/tests/cst.rs index 484d84259..8a2a25b8c 100644 --- a/parser/src/parser/tests/cst.rs +++ b/parser/src/parser/tests/cst.rs @@ -985,6 +985,109 @@ rule test : foo bar baz { │ └─ ident "baz" ├─ LPAREN "(" └─ RPAREN ")" +"#, + ), + //////////////////////////////////////////////////////////// + ( + line!(), + GrammarRule::term, + r#"#a in (1_000..200_)"#, + r##" + term + └─ primary_expr + ├─ pattern_count "#a" + ├─ k_IN "in" + └─ range + ├─ LPAREN "(" + ├─ expr + │ └─ term + │ └─ primary_expr + │ └─ integer_lit "1_000" + ├─ DOT_DOT ".." + ├─ expr + │ └─ term + │ └─ primary_expr + │ └─ integer_lit "200_" + └─ RPAREN ")" +"##, + ), + //////////////////////////////////////////////////////////// + ( + line!(), + GrammarRule::expr, + r#"0x0_2 | 0o00_1 & 0x03_"#, + r#" + expr + ├─ term + │ └─ primary_expr + │ └─ integer_lit "0x0_2" + ├─ BITWISE_OR "|" + ├─ term + │ └─ primary_expr + │ └─ integer_lit "0o00_1" + ├─ BITWISE_AND "&" + └─ term + └─ primary_expr + └─ integer_lit "0x03_" +"#, + ), + //////////////////////////////////////////////////////////// + ( + line!(), + GrammarRule::expr, + r#"0_2_2 | 0x00000_11 & 0o05_5"#, + r#" + expr + ├─ term + │ └─ primary_expr + │ └─ integer_lit "0_2_2" + ├─ BITWISE_OR "|" + ├─ term + │ └─ primary_expr + │ └─ integer_lit "0x00000_11" + ├─ BITWISE_AND "&" + └─ term + └─ primary_expr + └─ integer_lit "0o05_5" +"#, + ), + //////////////////////////////////////////////////////////// + ( + line!(), + GrammarRule::boolean_expr, + r#"2.5_5 * 2__3 * -1.0_1 == 5_55.05 + -(1_1)"#, + r#" + boolean_expr + └─ boolean_term + ├─ expr + │ ├─ term + │ │ └─ primary_expr + │ │ └─ float_lit "2.5_5" + │ ├─ MUL "*" + │ ├─ term + │ │ └─ primary_expr + │ │ └─ integer_lit "2__3" + │ ├─ MUL "*" + │ └─ term + │ └─ primary_expr + │ └─ float_lit "-1.0_1" + ├─ EQ "==" + └─ expr + ├─ term + │ └─ primary_expr + │ └─ float_lit "5_55.05" + ├─ ADD "+" + └─ term + └─ primary_expr + ├─ MINUS "-" + └─ term + └─ primary_expr + ├─ LPAREN "(" + ├─ expr + │ └─ term + │ └─ primary_expr + │ └─ integer_lit "1_1" + └─ RPAREN ")" "#, ), ]; diff --git a/parser/src/parser/tests/testdata/literals.yaml b/parser/src/parser/tests/testdata/literals.yaml index 6dc8ce56d..badfc2be4 100644 --- a/parser/src/parser/tests/testdata/literals.yaml +++ b/parser/src/parser/tests/testdata/literals.yaml @@ -118,4 +118,19 @@ ├─ 1MB └─ 1024KB +############################################################################### + +- rule: | + rule test { + condition: + 1_000MB == 10_24KB + } + ast: | + root + └─ rule test + └─ condition + └─ eq + ├─ 1_000MB + └─ 10_24KB + ############################################################################### \ No newline at end of file