aboutsummaryrefslogtreecommitdiff
path: root/lib/qsp_expression.mly
diff options
context:
space:
mode:
Diffstat (limited to 'lib/qsp_expression.mly')
-rw-r--r--lib/qsp_expression.mly88
1 files changed, 88 insertions, 0 deletions
diff --git a/lib/qsp_expression.mly b/lib/qsp_expression.mly
new file mode 100644
index 0000000..07da032
--- /dev/null
+++ b/lib/qsp_expression.mly
@@ -0,0 +1,88 @@
+(* %start <(Elements.pos) Elements.exppression>expression *)
+
+%%
+
+%public arguments(X):
+ (** This rule allow the difference between elements with a single argument
+ (when the separator is required) which allow to write a spectif case when
+ we only have one element.
+ *)
+ | hd = X
+ COMA
+ tl = separated_nonempty_list(COMA, X)
+ { hd :: tl }
+ (** The case where we have nothing is easy to manage here *)
+ |
+ { [] }
+ (** The remaining case (only one argument) is handled outside of this
+ block: if we have a single argument we don’t have to bother with the
+ paren, they belongs to the expression.
+ *)
+
+argument(X):
+ | a = delimited(L_PAREN, arguments(X), R_PAREN) { a }
+ | a = X { [ a ] }
+
+(** Declare an expression *)
+%public expression:
+ | ex = delimited(L_PAREN, expression, R_PAREN)
+ { ex }
+ | op = unary_operator
+ expr = expression
+ { Analyzer.Expression.uoperator $loc op expr }
+ %prec NO
+ |
+ expr1 = expression
+ op = binary_operator
+ expr2 = expression
+ { Analyzer.Expression.boperator $loc op expr1 expr2 }
+ %prec EQUAL
+ | v = LITERAL { Analyzer.Expression.literal $loc v }
+ | i = INTEGER { Analyzer.Expression.integer $loc i }
+ | v = variable { Analyzer.Expression.ident v }
+ %prec p_variable
+ | k = FUNCTION
+ arg = argument(expression)
+ {
+ (Analyzer.Expression.function_ $loc k arg)
+ }
+
+unary_operator:
+ | OBJ
+ | LOC
+ | NO { T.No }
+ | MINUS { T.Neg }
+ | PLUS { T.Add }
+
+%inline binary_operator:
+ | EQUAL { T.Eq }
+ | LT GT { T.Neq }
+ | EXCLAMATION { T.Neq }
+ | PLUS { T.Plus }
+ | MINUS { T.Minus }
+ | STAR { T.Product }
+ | DIV { T.Div }
+ | MOD { T.Mod }
+ | GT { T.Gt }
+ | LT { T.Lt }
+ | GT EQUAL { T.Gte }
+ | LT EQUAL { T.Lte }
+ | EQUAL GT { T.Gte }
+ | EQUAL LT { T.Lte }
+ | AND { T.And }
+ | OR { T.Or }
+
+(** Declare a variable, either in the assignation (let var = …) or as a
+ reference is an expression
+ *)
+%public variable:
+ | name = IDENT
+ brackets = delimited(L_BRACKET, expression?, R_BRACKET)?
+ {
+ let index = match brackets with
+ | None ->
+ (* No declaration, consider index at 0 *)
+ Some (Analyzer.Expression.integer dummy_pos "0")
+ | Some other -> other in
+ Analyzer.Expression.{ pos = $loc ; name ; index }
+ }