diff options
Diffstat (limited to 'lib/qparser/qsp_expression.mly')
-rw-r--r-- | lib/qparser/qsp_expression.mly | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/lib/qparser/qsp_expression.mly b/lib/qparser/qsp_expression.mly new file mode 100644 index 0000000..06cfadd --- /dev/null +++ b/lib/qparser/qsp_expression.mly @@ -0,0 +1,86 @@ +(* %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. + *) + +%inline 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 } + | 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 + | 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 } + | AND { T.And } + | GT EQUAL { T.Gte } + | LT EQUAL { T.Lte } + | EQUAL GT { T.Gte } + | EQUAL LT { T.Lte } + | 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 *) + None + | Some other -> other in + Analyzer.Expression.{ pos = $loc ; name ; index } + } |