%% %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 = delimited(TEXT_MARKER, literal*, TEXT_MARKER) { 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) } | k = FUNCTION_NOARGS { (Analyzer.Expression.function_ $loc k []) } literal: | v = LITERAL { Qsp_syntax.T.Text v } | e = delimited(ENTER_EMBED, expression, LEAVE_EMBED) { Qsp_syntax.T.Expression e } 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 Qsp_syntax.S.{ pos = $loc ; name ; index; local = false } }