use std::sync::Arc;
use swiftlet::grammar::Algorithm;
use swiftlet::{ParserConfig, Swiftlet};
#[macro_use]
mod common;
multi_test!(
rule_clr_simple_query,
rule_earley_simple_query,
r#"
start: select_stmt
select_stmt: "select"i columns "from"i table_name
columns: "*" | _columns
_columns: column ("," column)*
column: NAME
table_name: NAME
NAME: /[a-zA-Z][a-zA-Z1-9_]+/
%import WS
%ignore WS
"#,
"select col1, col2 from stat_table",
"start",
Algorithm::CLR,
Algorithm::Earley
);
multi_test!(
rule_clr_simple_query_with_sub_query,
rule_earley_simple_query_with_sub_query,
r#"
start: select_stmt
select_stmt: "select"i columns "from"i table_name
columns: "*" | _columns
_columns: column ("," column)*
column: NAME ("as" alias)?
table_name: NAME | "(" start ")" "as"i alias
alias: NAME
NAME: /[a-zA-Z][a-zA-Z1-9_]+/
%import WS
%ignore WS
"#,
"select col1, col2 from (select col3 as col1, col4 as col2 from stat_table) as tb1",
"start",
Algorithm::CLR,
Algorithm::Earley
);
multi_test_multi_input_texts!(
rule_clr_sql_column_case_expr,
rule_earley_sql_column_case_expr,
r#"
start: column_expr
column_expr: func
| column
| case
| literal
| condition
| NULL
func: func_name "(" args ")"
args: column_expr ("," column_expr)*
case: "case"i when_stmt+ else_stmt? "end"i
when_stmt: "when"i column_expr "then"i column_expr
else_stmt: "else"i column_expr
condition: column_expr comparator column_expr
comparator: "=" -> eq
| "!=" -> ne
| ">=" -> ge
| "<=" -> le
| "<" -> gt
| ">" -> lt
column: NAME
func_name: NAME
literal: INT | DECIMAL | STRING
STRING: /'[a-zA-Z0-9%_ ]+'/
NAME: /[a-zA-Z][a-zA-Z1-9_]+/
%import (WS, INT, DECIMAL)
%ignore WS
"#,
[
"SUM(Sales)",
"IF_NULL(Sales, 1)",
"IF_ZERO(Sales, NULL)",
"SUM(Sales > 5)",
"SUM(CASE WHEN Sales > 5 THEN 1 ELSE 2 END)",
"SUM(Sales) > 20",
"SUM(Cost_Price) > SUM(Selling_Price)",
"CASE WHEN Sales > 10 THEN 'Greater than 10' ELSE 'Less than 10' END",
"CASE WHEN Sales > 10 THEN 'Greater than 10' END",
"CASE WHEN SUM(Sales) > 10 THEN 'Aggregate value is greater than 10' ELSE 'Aggregate value is less than or equals to 10' END",
],
"start",
Algorithm::CLR,
Algorithm::Earley
);
multi_test!(
rule_clr_add_two_numbers,
rule_earley_add_two_numbers,
r#"
start: expr
expr: (expr "+")? t
t: INT
%import (WS, INT)
%ignore WS
"#,
"1 + 2",
"start",
Algorithm::CLR,
Algorithm::Earley
);
multi_test!(
rule_clr_add_multi_numbers,
rule_earley_add_multi_numbers,
r#"
start: expr
expr: expr "+" t | t
t: INT
%import (WS, INT)
%ignore WS
"#,
"1 + 2 + 3 + 4 + 5",
"start",
Algorithm::CLR,
Algorithm::Earley
);
multi_test!(
rule_clr_bodmas,
rule_earley_bodmas,
r#"
start: expr
expr: expr "+" factor -> add
| expr "-" factor -> sub
| factor
factor: factor "*" term -> multiply
| factor "/" term -> divide
| term
term: "(" expr ")" | INT
%import (WS, INT)
%ignore WS
"#,
"3 * (2 * (3 + 4) - 5)",
"start",
Algorithm::CLR,
Algorithm::Earley
);