From 33cc92a397f93f5ac33e98e92fb11b617619c1b6 Mon Sep 17 00:00:00 2001 From: Johan Girod Date: Thu, 19 Sep 2019 11:45:16 +0200 Subject: [PATCH] =?UTF-8?q?:gear:=20ajoute=20l'op=C3=A9ration=20unaire=20d?= =?UTF-8?q?e=20n=C3=A9gation=20=C3=A0=20la=20grammaire?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/engine/grammar.ne | 25 +++++++++++++++---------- source/engine/grammarFunctions.js | 9 ++++++++- test/mécanismes/expressions.yaml | 29 +++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 11 deletions(-) diff --git a/source/engine/grammar.ne b/source/engine/grammar.ne index dd2a90171..3798cc5be 100644 --- a/source/engine/grammar.ne +++ b/source/engine/grammar.ne @@ -5,7 +5,7 @@ @preprocessor esmodule @{% -import {string, filteredVariable, variable, temporalVariable, operation, boolean, number, percentage } from './grammarFunctions' +import {string, filteredVariable, variable, temporalVariable, binaryOperation, unaryOperation, boolean, number, percentage } from './grammarFunctions' const moo = require("moo"); @@ -23,14 +23,14 @@ const lexer = moo.compile({ ')': ')', '[': '[', ']': ']', - comparisonOperator: ['>','<','>=','<=','=','!='], - additionSubstractionOperator: /[\+-]/, - multiplicationDivisionOperator: ['*','/'], + comparison: ['>','<','>=','<=','=','!='], + additionSubstraction: /[\+-]/, + multiplicationDivision: ['*','/'], temporality: ['annuel' , 'mensuel'], words: new RegExp(words), string: /'[ \t\.'a-zA-Z\-\u00C0-\u017F0-9 ]+'/, dot: ' . ', - _: { match: /[\s]/, lineBreaks: true } + space: { match: /[\s]+/, lineBreaks: true } }); %} @@ -40,6 +40,7 @@ main -> AdditionSubstraction {% id %} | Comparison {% id %} | NonNumericTerminal {% id %} + | Negation {% id %} NumericTerminal -> Variable {% id %} @@ -47,11 +48,14 @@ NumericTerminal -> | FilteredVariable {% id %} | number {% id %} +Negation -> + "-" %space Parentheses {% unaryOperation('calculation') %} Parentheses -> "(" AdditionSubstraction ")" {% ([,e]) => e %} + | "(" Negation ")" {% ([,e]) => e %} | NumericTerminal {% id %} -Comparison -> Comparable %_ %comparisonOperator %_ Comparable {% operation('comparison')%} +Comparison -> Comparable %space %comparison %space Comparable {% binaryOperation('comparison')%} Comparable -> ( AdditionSubstraction | NonNumericTerminal) {% ([[e]]) => e %} @@ -65,22 +69,22 @@ Variable -> %words (%dot %words {% ([,words]) => words %}):* {% variable %} Filter -> "[" %words "]" {% ([,filter]) => filter %} -FilteredVariable -> Variable %_ Filter {% filteredVariable %} +FilteredVariable -> Variable %space Filter {% filteredVariable %} TemporalTransform -> "[" %temporality "]" {% ([,temporality]) => temporality %} -TemporalVariable -> Variable %_ TemporalTransform {% temporalVariable %} +TemporalVariable -> Variable %space TemporalTransform {% temporalVariable %} #----- # Addition and subtraction AdditionSubstraction -> - AdditionSubstraction %_ %additionSubstractionOperator %_ MultiplicationDivision {% operation('calculation') %} + AdditionSubstraction %space %additionSubstraction %space MultiplicationDivision {% binaryOperation('calculation') %} | MultiplicationDivision {% id %} # Multiplication and division MultiplicationDivision -> - MultiplicationDivision %_ %multiplicationDivisionOperator %_ Parentheses {% operation('calculation') %} + MultiplicationDivision %space %multiplicationDivision %space Parentheses {% binaryOperation('calculation') %} | Parentheses {% id %} @@ -91,4 +95,5 @@ boolean -> number -> %number {% number %} | %percentage {% percentage %} + string -> %string {% string %} \ No newline at end of file diff --git a/source/engine/grammarFunctions.js b/source/engine/grammarFunctions.js index 6195c8a86..7bbc62707 100644 --- a/source/engine/grammarFunctions.js +++ b/source/engine/grammarFunctions.js @@ -2,13 +2,20 @@ The advantage of putting them here is to get prettier's JS formatting, since Nealrey doesn't support it https://github.com/kach/nearley/issues/310 */ import { parseUnit } from 'Engine/units' -export let operation = operationType => ([A, , operator, , B]) => ({ +export let binaryOperation = operationType => ([A, , operator, , B]) => ({ [operator]: { operationType, explanation: [A, B] } }) +export let unaryOperation = operationType => ([operator, , A]) => ({ + [operator]: { + operationType, + explanation: [number([{ value: '0' }]), A] + } +}) + export let filteredVariable = ( [{ variable }, , { value: filter }], l, diff --git a/test/mécanismes/expressions.yaml b/test/mécanismes/expressions.yaml index fbdf41127..916bb571e 100644 --- a/test/mécanismes/expressions.yaml +++ b/test/mécanismes/expressions.yaml @@ -234,3 +234,32 @@ formule: -5 * -10 exemples: - valeur attendue: 50 + +- test: négation de variable + formule: '- salaire de base' + exemples: + - situation: + salaire de base: 3000 + valeur attendue: -3000 + +- test: négation d'expressions + formule: '- (10 * 3 + 5)' + exemples: + - valeur attendue: -35 + +- test: variables négatives dans expression + formule: 10% * (- salaire de base) + exemples: + - situation: + salaire de base: 3000 + valeur attendue: -300 +# TODO +# - test: expression sur plusieurs lignes +# formule: > +# salaire de base +# + 2000 +# = 3000 +# exemples: +# - situation: +# salaire de base: 1000 +# - valeur attendue: true