From 2e085dd71c1ff96fb7e30297f342715420fbb91c Mon Sep 17 00:00:00 2001 From: Mael Date: Thu, 16 May 2019 15:58:30 +0200 Subject: [PATCH] :sparkles: Externalisation des fonctions de retraitement de la grammaire --- source/engine/grammar.ne | 74 ++++++++----------------------- source/engine/grammarFunctions.js | 72 ++++++++++++++++++++++++------ 2 files changed, 76 insertions(+), 70 deletions(-) diff --git a/source/engine/grammar.ne b/source/engine/grammar.ne index 9c19a3b05..3ba147294 100644 --- a/source/engine/grammar.ne +++ b/source/engine/grammar.ne @@ -1,3 +1,9 @@ +@preprocessor esmodule + +@{% +import {string, filteredVariable, variable, temporalVariable, operation, boolean, number, percentage } from './grammarFunctions' +%} + main -> AS {% id %} | Comparison {% id %} @@ -15,14 +21,7 @@ Parentheses -> "(" AS ")" {% ([,e]) => e %} ComparisonOperator -> ">" | "<" | ">=" | "<=" | "=" | "!=" -Comparison -> Comparable _ ComparisonOperator _ Comparable {% ([A, , operator, , B]) => ({ - [operator]: - { - type: 'comparison', - explanation: - [A, B] - } -}) %} +Comparison -> Comparable _ ComparisonOperator _ Comparable {% operation('comparison')%} Comparable -> ( AS | NonNumericTerminal) {% ([[e]]) => e %} @@ -34,11 +33,11 @@ NonNumericTerminal -> NegatedVariable -> "≠" _ Variable {% ([,,{variable}]) => ({'≠': {explanation: variable} }) %} -FilteredVariable -> Variable _ Filter {% ([{variable},,filter],l,reject) => ['mensuel', 'annuel'].includes(filter) ? reject : ({filter: {filter, explanation: variable}}) %} +FilteredVariable -> Variable _ Filter {% filteredVariable %} Filter -> "[" VariableFragment "]" {% ([,filter]) => filter %} -TemporalVariable -> Variable _ TemporalTransform {% ([{variable},,temporalTransform]) => ({'temporalTransform': {explanation: variable, temporalTransform} }) %} +TemporalVariable -> Variable _ TemporalTransform {% temporalVariable %} TemporalTransform -> "[" Temporality "]" {% d =>d[1] %} @@ -47,15 +46,7 @@ Temporality -> "annuel" | "mensuel" {% id %} # Addition and subtraction -AS -> AS _ ASOperator _ MD {% ([A, , operator, , B]) => ({ - [operator]: - { - type: 'calculation', - explanation: - [A, B] - } -}) %} - +AS -> AS _ ASOperator _ MD {% operation('calculation') %} | MD {% id %} @@ -66,16 +57,7 @@ MDOperator -> "*" {% id %} | "/" {% id %} # Multiplication and division -MD -> MD _ MDOperator _ Parentheses {% -([A, , operator, , B]) => ({ - [operator]: - { - type: 'calculation', - explanation: - [A, B] - } -}) %} - +MD -> MD _ MDOperator _ Parentheses {% operation('calculation') %} | Parentheses {% id %} Term -> Variable {% id %} @@ -84,20 +66,9 @@ Term -> Variable {% id %} | percentage {% id %} Variable -> VariableFragment (_ Dot _ VariableFragment {% ([,,,fragment]) => fragment %}):* -{% ([firstFragment, nextFragments], l, reject) => { -let fragments = [firstFragment, ...nextFragments] -if (fragments.length === 1 && ['oui', 'non'].includes(fragments[0])) - return reject -return ({variable: { - fragments -}}) }%} +{% variable %} -String -> "'" [ .'a-zA-Z\-\u00C0-\u017F ]:+ "'" {% d => ({constant: { - - type: 'string', - nodeValue: d[1].join(''), - rawNode: d[1].join('') -}}) %} +String -> "'" [ .'a-zA-Z\-\u00C0-\u017F ]:+ "'" {% string %} VariableFragment -> VariableWord (_ VariableWord {% d=> ' ' + d[1] %}):* {% d => d[0] + d[1].join('') %} @@ -109,20 +80,11 @@ Dot -> [\.] {% d => null %} _ -> [\s] {% d => null %} -number -> [0-9]:+ ([\.] [0-9]:+):? {% d => ({constant:{ +number -> [0-9]:+ ([\.] [0-9]:+):? {% number %} - rawNode: d, -nodeValue: parseFloat(d[0].join("")+(d[1]?(d[1][0]+d[1][1].join("")):""))}}) %} +percentage -> [0-9]:+ ([\.] [0-9]:+):? [\%] {% percentage %} -percentage -> [0-9]:+ ([\.] [0-9]:+):? [\%] {% d => ({ 'constant':{ - - rawNode: d, -type: 'percentage', nodeValue: parseFloat(d[0].join("")+(d[1]?(d[1][0]+d[1][1].join("")):""))/100}}) %} - - -Boolean -> ("oui" - | "non" ) {% ([val])=> ({constant:{ - - rawNode: val, - type: 'boolean', nodeValue: {'oui': true, 'non': false}[val]}}) %} +Boolean -> ( + "oui" + | "non" ) {% boolean %} diff --git a/source/engine/grammarFunctions.js b/source/engine/grammarFunctions.js index 0f5c75c48..3b0087729 100644 --- a/source/engine/grammarFunctions.js +++ b/source/engine/grammarFunctions.js @@ -1,19 +1,63 @@ -import React from 'react' +/* Those are postprocessor functions for the Nearley grammar.ne. +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 */ -export let boolean = nodeValue => ({ - category: 'boolean', - nodeValue: nodeValue, - // eslint-disable-next-line - jsx: () => {rawNode} +export let operation = type => ([A, , operator, , B]) => ({ + [operator]: { + type: type, + explanation: [A, B] + } +}) + +export let filteredVariable = ([{ variable }, , filter], l, reject) => + ['mensuel', 'annuel'].includes(filter) + ? reject + : { filter: { filter, explanation: variable } } + +export let temporalVariable = ([{ variable }, , temporalTransform]) => ({ + temporalTransform: { explanation: variable, temporalTransform } +}) + +export let variable = ([firstFragment, nextFragments], l, reject) => { + let fragments = [firstFragment, ...nextFragments] + if (fragments.length === 1 && ['oui', 'non'].includes(fragments[0])) + return reject + return { + variable: { + fragments + } + } +} + +export let number = d => ({ + constant: { + rawNode: d, + nodeValue: parseFloat( + d[0].join('') + (d[1] ? d[1][0] + d[1][1].join('') : '') + ) + } }) export let percentage = d => ({ - // We don't need to handle category == 'value' because YAML then returns it as - // numerical value, not a String: it goes to treatNumber - nodeValue: - parseFloat(d[0].join('') + (d[1] ? d[1][0] + d[1][1].join('') : '')) / 100, - category: 'percentage', - // eslint-disable-next-line - jsx: () => {rawNode.split('%')[0]} % - //on ajoute l'espace nécessaire en français avant le pourcentage + constant: { + rawNode: d, + type: 'percentage', + nodeValue: + parseFloat(d[0].join('') + (d[1] ? d[1][0] + d[1][1].join('') : '')) / 100 + } +}) + +export let boolean = ([val]) => ({ + constant: { + rawNode: val, + type: 'boolean', + nodeValue: { oui: true, non: false }[val] + } +}) + +export let string = d => ({ + constant: { + type: 'string', + nodeValue: d[1].join(''), + rawNode: d[1].join('') + } })