✨ Externalisation des fonctions de retraitement de la grammaire
parent
dc08b0fd0f
commit
2e085dd71c
|
@ -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 %}
|
||||
|
||||
|
|
|
@ -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: () => <span className="boolean">{rawNode}</span>
|
||||
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: () => <span className="value">{rawNode.split('%')[0]} %</span>
|
||||
//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('')
|
||||
}
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue