[moteur] Le parser Nearley renvoit maintenant un AST similaire au notre
Il reste à le reparser pour résoudre les variables en fonction de la situation, calculer les nodeValues, ajouter les missingVariables Puis implémenter les modifieurs de temps Puis ajouter le prorata à la multiplication \ \ \\ \\ >\/7 _.-(6' \ (=___._/` \ ) \ | / / | / > / j < _\ _.-' : ``. \ r=._\ `. <`\\_ \ .`-. \ r-7 `-. ._ ' . `\ \`, `-.`7 7) ) \/ \| \' / `-._ || .' cjr \\ ( 10mar02 >\ > ,.-' >.' <.'_.'' <'pull/6/head
parent
578153a3b7
commit
c1cfb20bf1
|
@ -17,6 +17,7 @@
|
|||
"install": "^0.8.2",
|
||||
"js-yaml": "^3.7.0",
|
||||
"marked": "^0.3.6",
|
||||
"nearley": "^2.7.14",
|
||||
"npm": "^4.0.3",
|
||||
"ramda": "^0.23.0",
|
||||
"react": "^15.0.1",
|
||||
|
@ -52,6 +53,7 @@
|
|||
"html-loader": "^0.4.2",
|
||||
"img-loader": "^1.2.2",
|
||||
"json-loader": "^0.5.4",
|
||||
"nearley-loader": "0.0.2",
|
||||
"postcss-loader": "^1.2.2",
|
||||
"redux-devtools": "^3.2.0",
|
||||
"redux-devtools-dock-monitor": "^1.1.1",
|
||||
|
|
|
@ -5,13 +5,13 @@
|
|||
collecteur: OPCA
|
||||
références:
|
||||
Code du travail - Article L6322-37 : https://www.legifrance.gouv.fr/affichCodeArticle.do?idArticle=LEGIARTI000022234996&cidTexte=LEGITEXT000006072050
|
||||
|
||||
non applicable si:
|
||||
l'une de ces conditions:
|
||||
- événements . CDD poursuivi en CDI
|
||||
- motif . saisonnier
|
||||
- motif . jeune vacances
|
||||
- contrat aidé
|
||||
#
|
||||
# non applicable si:
|
||||
# l'une de ces conditions:
|
||||
# - événements . CDD poursuivi en CDI
|
||||
# - motif . saisonnier
|
||||
# - motif . jeune vacances
|
||||
# - contrat aidé
|
||||
|
||||
# Données de test #
|
||||
# non applicable si:
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
# CalcExpression
|
||||
- salaire de base * 3
|
||||
|
||||
- Salariat . salaire de base * 3
|
||||
- congés non pris / 25
|
||||
|
||||
|
|
|
@ -1,83 +1,48 @@
|
|||
main -> CalcExpression {% d => (['CalcExpression', ...d]) %}
|
||||
| BooleanVariableExpression {% d => (['BooleanVariableExpression', ...d]) %}
|
||||
| ModifiedVariable {% d => (['ModifiedVariable', ...d]) %}
|
||||
| Comparison {% d => (['Comparison', ...d]) %}
|
||||
@{% function buildNode(type, d){return ({nodeType: type, explanation: d})} %}
|
||||
|
||||
Comparison -> Comparable _ ComparisonOperator _ Comparable
|
||||
main ->
|
||||
CalcExpression {% id %}
|
||||
| Variable {% id %}
|
||||
| ModifiedVariable {% id %}
|
||||
| Comparison {% id %}
|
||||
|
||||
Comparable -> (int | CalcExpression | Variable)
|
||||
Comparison -> Comparable _ ComparisonOperator _ Comparable {% d => ({nodeType: 'Comparison', operator: d[2][0], explanation: [d[0], d[4]]}) %}
|
||||
|
||||
Comparable -> (int | CalcExpression | Variable) {% d => d[0][0] %}
|
||||
|
||||
ComparisonOperator -> ">" | "<" | ">=" | "<=" | "="
|
||||
|
||||
ModifiedVariable -> Variable _ Modifier {% d => ({nodeType: 'ModifiedVariable', modifier: d[2], variable: d[0] }) %}
|
||||
|
||||
ModifiedVariable -> Variable _ Modifier
|
||||
Modifier -> "[" TemporalModifier "]" {% d =>d[1][0] %}
|
||||
|
||||
Modifier -> "[" TemporalModifier "]"
|
||||
TemporalModifier -> "annuel" | "mensuel" | "jour ouvré" {% id %}
|
||||
|
||||
TemporalModifier -> "annuel" | "mensuel" | "jour ouvré"
|
||||
CalcExpression -> Term _ ArithmeticOperator _ Term {% d => ({nodeType: 'CalcExpression', operator: d[2], explanation: [d[0], d[4]]}) %}
|
||||
|
||||
CalcExpression -> Term _ ArithmeticOperator _ Term
|
||||
Term -> Variable {% id %}
|
||||
| int {% id %}
|
||||
|
||||
Term -> Variable
|
||||
| int
|
||||
|
||||
ArithmeticOperator -> "+" | "-" | "*" | "/"
|
||||
|
||||
BooleanVariableExpression -> ("!" _):? Variable {% d => (['BooleanVariableExpression', ...d]) %}
|
||||
ArithmeticOperator -> "+" {% id %}
|
||||
| "-" {% id %}
|
||||
| "*" {% id %}
|
||||
| "/" {% id %}
|
||||
|
||||
|
||||
VariableWord -> [a-zA-Z\u00C0-\u017F]:+ {% d => (['VariableWord', ...d]) %}
|
||||
|
||||
Variable -> VariableFragment (_ Dot _ VariableFragment):* {% d => (['Variable', ...d]) %}
|
||||
|
||||
VariableFragment -> VariableWord (_ VariableWord):* {% d => (['VariableFragment', ...d]) %}
|
||||
|
||||
Dot -> [\.] {% d => (['Dot', ...d]) %}
|
||||
|
||||
_ -> [\s] {% function(d) {return null } %}
|
||||
# BooleanVariableExpression -> ("!" _):? Variable {% d => (['BooleanVariableExpression', ...d]) %}
|
||||
|
||||
|
||||
Variable -> VariableFragment (_ Dot _ VariableFragment {% d => d[3] %}):* {% d => ({nodeType: 'Variable', fragments: [d[0], ...d[1]] }) %}
|
||||
|
||||
|
||||
# PEMDAS!
|
||||
# We define each level of precedence as a nonterminal.
|
||||
VariableFragment -> VariableWord (_ VariableWord {% d=> ' ' + d[1] %}):* {% d => d[0] + ' ' + d[1].join('') %}
|
||||
|
||||
# Parentheses
|
||||
P -> "(" _ AS _ ")" {% function(d) {return {type:'P', d:d, v:d[2].v}} %}
|
||||
| N {% id %}
|
||||
|
||||
# Exponents
|
||||
E -> P _ "^" _ E {% function(d) {return {type:'E', d:d, v:Math.pow(d[0].v, d[4].v)}} %}
|
||||
| P {% id %}
|
||||
VariableWord -> [a-zA-Z\u00C0-\u017F]:+ {% d => d[0].join('') %}
|
||||
|
||||
# Multiplication and division
|
||||
MD -> MD _ "*" _ E {% function(d) {return {type: 'M', d:d, v:d[0].v*d[4].v}} %}
|
||||
| MD _ "/" _ E {% function(d) {return {type: 'D', d:d, v:d[0].v/d[4].v}} %}
|
||||
| E {% id %}
|
||||
Dot -> [\.] {% d => null %}
|
||||
|
||||
# Addition and subtraction
|
||||
AS -> AS _ "+" _ MD {% function(d) {return {type:'A', d:d, v:d[0].v+d[4].v}} %}
|
||||
| AS _ "-" _ MD {% function(d) {return {type:'S', d:d, v:d[0].v-d[4].v}} %}
|
||||
| MD {% id %}
|
||||
_ -> [\s] {% d => null %}
|
||||
|
||||
# A number or a function of a number
|
||||
N -> float {% id %}
|
||||
| "sin" _ P {% function(d) {return {type:'sin', d:d, v:Math.sin(d[2].v)}} %}
|
||||
| "cos" _ P {% function(d) {return {type:'cos', d:d, v:Math.cos(d[2].v)}} %}
|
||||
| "tan" _ P {% function(d) {return {type:'tan', d:d, v:Math.tan(d[2].v)}} %}
|
||||
|
||||
| "asin" _ P {% function(d) {return {type:'asin', d:d, v:Math.asin(d[2].v)}} %}
|
||||
| "acos" _ P {% function(d) {return {type:'acos', d:d, v:Math.acos(d[2].v)}} %}
|
||||
| "atan" _ P {% function(d) {return {type:'atan', d:d, v:Math.atan(d[2].v)}} %}
|
||||
|
||||
| "pi" {% function(d) {return {type:'pi', d:d, v:Math.PI}} %}
|
||||
| "e" {% function(d) {return {type:'e', d:d, v:Math.E}} %}
|
||||
| "sqrt" _ P {% function(d) {return {type:'sqrt', d:d, v:Math.sqrt(d[2].v)}} %}
|
||||
| "ln" _ P {% function(d) {return {type:'ln', d:d, v:Math.log(d[2].v)}} %}
|
||||
|
||||
# I use `float` to basically mean a number with a decimal point in it
|
||||
float ->
|
||||
int "." int {% function(d) {return {v:parseFloat(d[0].v + d[1].v + d[2].v)}} %}
|
||||
| int {% function(d) {return {v:parseInt(d[0].v)}} %}
|
||||
|
||||
int -> [0-9]:+ {% function(d) {return {v:d[0].join("")}} %}
|
||||
int -> [0-9]:+ {% d => ({nodeType: 'value', value: d[0].join("")}) %}
|
||||
|
|
|
@ -2,6 +2,10 @@ import {rules, findRuleByName, parentName} from './rules'
|
|||
import {recognizeExpression} from './expressions'
|
||||
import R from 'ramda'
|
||||
import knownMecanisms from './known-mecanisms.yaml'
|
||||
import { Parser } from 'nearley'
|
||||
import Grammar from './grammar.ne'
|
||||
|
||||
let nearley = new Parser(Grammar.ParserRules, Grammar.ParserStart)
|
||||
|
||||
/*
|
||||
Dans ce fichier, les règles YAML sont parsées.
|
||||
|
@ -234,6 +238,8 @@ let treat = (situationGate, rule) => rawNode => {
|
|||
|
||||
if (k === 'multiplication') {
|
||||
let base = v['assiette'],
|
||||
parsed = nearley.feed(base),
|
||||
yaya = console.log('parsed', parsed),
|
||||
[baseVariableName] = recognizeExpression(rule, base),
|
||||
baseValue = situationGate(baseVariableName),
|
||||
rateNode = treat(situationGate, rule)({taux: v['taux']}),
|
||||
|
@ -255,7 +261,7 @@ let treat = (situationGate, rule) => rawNode => {
|
|||
missingVariables: baseValue == null ? [baseVariableName] : []
|
||||
},
|
||||
rate: rateNode,
|
||||
prorata:
|
||||
// prorata:
|
||||
//TODO limit: 'plafond'
|
||||
//TODO multiplier: 'multiplicateur'
|
||||
}
|
||||
|
@ -328,99 +334,6 @@ let treatRuleRoot = (situationGate, rule) => R.evolve({ // -> Voilà les attribu
|
|||
})(rule)
|
||||
|
||||
|
||||
let deriveRuleOld = (situationGate, rule) => pipe( // eslint-disable-line no-unused-vars
|
||||
toPairs,
|
||||
reduce(({missingVariables, computedValue}, [key, value]) => {
|
||||
if (key === 'concerne') {
|
||||
let [variableName, evaluation] = recognizeExpression(rule, value)
|
||||
// Si cette variable a été renseignée
|
||||
if (knownVariable(situationGate, variableName)) {
|
||||
// Si l'expression n'est pas vraie...
|
||||
if (!evaluation(situationGate)) {
|
||||
// On court-circuite toute la variable, et on n'a besoin d'aucune information !
|
||||
return reduced({missingVariables: []})
|
||||
} else {
|
||||
// Sinon, on continue
|
||||
return {missingVariables}
|
||||
}
|
||||
// sinon on demande la valeur de cette variable
|
||||
} else return { missingVariables: [...missingVariables, variableName] }
|
||||
}
|
||||
|
||||
if (key === 'non applicable si') {
|
||||
let conditions = value['l\'une de ces conditions']
|
||||
let [subVariableNames, reduced] = reduce(([variableNames], expression) => {
|
||||
let [variableName, evaluation] = recognizeExpression(rule, expression)
|
||||
if (knownVariable(situationGate, variableName)) {
|
||||
if (evaluation(situationGate)) {
|
||||
return reduced([[], true])
|
||||
} else {
|
||||
return [variableNames]
|
||||
}
|
||||
}
|
||||
return [[...variableNames, variableName]]
|
||||
}, [[], null])(conditions)
|
||||
|
||||
if (reduced) return reduced({missingVariables: []})
|
||||
else return {missingVariables: [...missingVariables, ...subVariableNames]}
|
||||
}
|
||||
|
||||
if (key === 'formule') {
|
||||
if (value['multiplication']) {
|
||||
let {assiette, taux} = value['multiplication']
|
||||
|
||||
// A propos de l'assiette
|
||||
let [assietteVariableName] = recognizeExpression(rule, assiette),
|
||||
assietteValue = situationGate(assietteVariableName),
|
||||
unknownAssiette = assietteValue == undefined
|
||||
|
||||
// Arrivés là, cette formule devrait être calculable !
|
||||
let {missingVariables: tauxMissingVariables = [], computedValue} = typeof taux !== 'string' ?
|
||||
do {
|
||||
let numericalLogic = taux['logique numérique']
|
||||
if (!numericalLogic) throw 'On ne sait pas pour l\'instant traiter ce mécanisme de taux'
|
||||
|
||||
let treatNumericalLogic = numericalLogic => {
|
||||
if (typeof numericalLogic == 'string') {
|
||||
return new Object({computedValue: assietteValue * transformPercentage(numericalLogic)})
|
||||
} else {
|
||||
return pipe(
|
||||
toPairs(),
|
||||
reduce(({missingVariables}, [expression, subLogic]) => {
|
||||
let [variableName, evaluation] = recognizeExpression(rule, expression)
|
||||
if (knownVariable(situationGate, variableName)) {
|
||||
if (evaluation(situationGate)) {
|
||||
return reduced(treatNumericalLogic(subLogic))
|
||||
} else {
|
||||
return {missingVariables}
|
||||
}
|
||||
} else return {missingVariables: [...missingVariables, variableName]}
|
||||
}, {missingVariables: []})
|
||||
)(numericalLogic)
|
||||
}}
|
||||
treatNumericalLogic(numericalLogic)
|
||||
} : ({computedValue: assietteValue * transformPercentage(taux)})
|
||||
|
||||
let formulaResult = {
|
||||
missingVariables: [
|
||||
...missingVariables,
|
||||
...(unknownAssiette ? [assietteVariableName] : []),
|
||||
...tauxMissingVariables
|
||||
],
|
||||
computedValue
|
||||
}
|
||||
|
||||
return computedValue != null ? reduced(formulaResult) : formulaResult
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return {missingVariables}
|
||||
}, {missingVariables: []}
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
/* Analyse the set of selected rules, and add derived information to them :
|
||||
- do they need variables that are not present in the user situation ?
|
||||
- if not, do they have a computed value or are they non applicable ?
|
||||
|
|
|
@ -35,6 +35,9 @@ module.exports = {
|
|||
{
|
||||
test: /\.(jpe?g|png|gif|svg)$/i,
|
||||
loader: 'url?limit=10000!img?progressive=true'
|
||||
}, {
|
||||
test: /\.ne$/,
|
||||
loader: 'nearley'
|
||||
}]
|
||||
},
|
||||
postcss: [
|
||||
|
|
Loading…
Reference in New Issue