aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChimrod <>2023-09-22 18:51:45 +0200
committerChimrod <>2023-09-22 18:51:45 +0200
commit557d60d5df5258a29ce964fac1f5ffdc625dcb2a (patch)
tree655f756fbbc2fa906eeef8d3f3a0af42af36c6f8
parent1aaf8ae4d48bb9404b8faef2ba55024a6d6bac23 (diff)
Correction in precedence order
-rw-r--r--lib/grammar.txt100
-rw-r--r--lib/tokens.mly2
-rw-r--r--test/qsp_parser_test.ml20
3 files changed, 121 insertions, 1 deletions
diff --git a/lib/grammar.txt b/lib/grammar.txt
new file mode 100644
index 0000000..d7208ef
--- /dev/null
+++ b/lib/grammar.txt
@@ -0,0 +1,100 @@
+location:
+ | LOCATION_START EOL*
+ line_statement*
+ LOCATION_END EOL*
+ EOF
+
+line_statement:
+ | COMMENT EOL+ // A comment
+ | COLUMN IDENT EOL* // A location
+ | instruction, line_sep
+ | inline_action line_sep
+ | ACT expression COLUMN EOL+ // ACT … END ACT
+ line_statement*
+ END ACT? // Yes you can have END or END ACT
+ line_sep
+ | IF expression COLUMN EOL+ // IF … END IF
+ line_statement*
+ elif*
+ else
+ END IF? // Yes you can have END or END IF
+ line_sep
+
+elif:
+ | ELIF
+ expression COLUMN EOL+
+ line_statement*
+
+else:
+ | ELSE EOL+
+ line_statement*
+ |
+
+line_sep:
+ | EOL+
+ | AMPERSAND+ EOL*
+
+
+instruction:
+ | expression
+ | let_assignation
+ | keyword argument(expression)
+
+keyword:
+ | STAR KEYWORD // A keyword starting with *
+ | KEYWORD
+
+let_assignation:
+ | assignation
+ variable
+ assignation_operator
+ expression
+
+assignation:
+ |
+ | LET
+ | SET
+
+assignation_operator:
+ | EQUAL
+ | INCR // +=
+ | DECR // -=
+
+inline_action:
+ | ACT expression COLUMN // There is a recursive code here
+ | IF expression COLUMN // Because ACT: can contains an IF: etc
+ (ELSE, instruction)? // complicated to flatten here.
+
+expression:
+ | delimited(l_paren, expression, r_paren)
+ | unary_operator expression
+ | expression binary_operator expression
+ | literal
+ | integer
+ | variable
+ | function argument(expression)
+
+unary_operator:
+ | OBJ
+ | LOC
+ | NO
+ | MINUS
+ | PLUS
+
+binary_operator:
+ | EQUAL
+ | LT GT // Different
+ | EXCLAMATION // Neg, not a comment here
+ | PLUS
+ | MINUS
+ | STAR // Not the first char of keyword here
+ | DIV
+ | MOD
+ | GT
+ | LT
+ | GT EQUAL
+ | LT EQUAL
+ | EQUAL GT // Alternative syntax
+ | EQUAL LT // Alternative syntax
+ | AND
+ | OR
diff --git a/lib/tokens.mly b/lib/tokens.mly
index 7f907a3..7720440 100644
--- a/lib/tokens.mly
+++ b/lib/tokens.mly
@@ -51,13 +51,13 @@ in favor of shifting.
(* Exclamation should have the lower priority because the comments shall never
take place of the statements
*)
-%right EXCLAMATION
%right NO
(* The priority for the variable should be lower than the equality priority
if I want to allow declare new variables *)
%nonassoc p_variable
%left AND OR
%right EQUAL GT LT GTE LTE
+%right EXCLAMATION
%left PLUS MINUS
%left STAR DIV
%left MOD
diff --git a/test/qsp_parser_test.ml b/test/qsp_parser_test.ml
index 4665737..ef19ed9 100644
--- a/test/qsp_parser_test.ml
+++ b/test/qsp_parser_test.ml
@@ -638,6 +638,25 @@ let test_precedence4 () =
let test_precedence5 () =
_test_instruction "clear()" Ast.[ Call (_position, "CLEAR", []) ]
+let test_precedence6 () =
+ _test_instruction "(1 = 0 and 2 ! 3)"
+ [
+ Ast.Expression
+ (Ast.BinaryOp
+ ( _position,
+ And,
+ Ast.BinaryOp
+ ( _position,
+ Eq,
+ Ast.Integer (_position, "1"),
+ Ast.Integer (_position, "0") ),
+ Ast.BinaryOp
+ ( _position,
+ Neq,
+ Ast.Integer (_position, "2"),
+ Ast.Integer (_position, "3") ) ));
+ ]
+
(** An identifier cannot start by a number *0 is a product and not an
identifier *)
let test_operator () =
@@ -719,6 +738,7 @@ let syntax =
Alcotest.test_case "Function rand" `Quick test_function2;
Alcotest.test_case "Precedence4" `Quick test_precedence4;
Alcotest.test_case "Precedence5" `Quick test_precedence5;
+ Alcotest.test_case "Precedence6" `Quick test_precedence6;
Alcotest.test_case "Operator" `Quick test_operator;
Alcotest.test_case "Operator2" `Quick test_operator2;
Alcotest.test_case "Dyneval" `Quick test_dyneval;