mercredi 16 octobre 2019

Ma première grammaire PEG.js

Afin de m'exercer à l'interprétation d'un langage personnalisé dans un de mes projets, je me suis exercé avec un exemple assez simple (c'est le cas de le dire 😁). J'ai décidé d'interpréter une expression de mon crû en nombre complexe.




Par exemple, si quelqu'un envoie en entrée
Complex(12, 12*3+45)
je dois simplement lui renvoyer
12+81i
 De même, pour
Complex(12)
je renvoie simplement 12.

La rédaction des règles d'interprétation

Pour cela, je me suis rendu sur le site https://pegjs.org/online, afin de pouvoir rédiger et tester directement mon "langage" en ligne.

Voici donc le code du langage dans sa version finale

Complex
= "Complex(" WhiteSpace? real:Additive WhiteSpace? "," 
  WhiteSpace? imag:Additive WhiteSpace? ")" {
  return "" + real + "+" + imag + "i"
}
/ "Complex(" WhiteSpace? real:Additive WhiteSpace? ")" {
  return real;
}

Additive
= left:Multiplicative WhiteSpace? "+" WhiteSpace? right:Multiplicative { 
  return left + right;
}
/ left:Multiplicative WhiteSpace? "-" WhiteSpace? right:Multiplicative { 
  return left - right; 
}
/ Multiplicative

Multiplicative
= left:Numeric WhiteSpace? "*" WhiteSpace? right:Numeric { 
  return left * right;
}
/ left:Numeric WhiteSpace? "/" WhiteSpace? right:Numeric { 
  return left / right;
}
/ Numeric

WhiteSpace
= [ ]+

Numeric
= integer: ([1-9][0-9]*) {
  return parseInt(text());
}
/ Zero

Zero
= "0" { return 0; }

              

Sans trop rentrer dans les détails (je vous invite à lire la documentation officielle pour en savoir un peu plus sur la syntaxe) :

  • J'attends en entrée une expression de la forme:
    • Complex(partieRéelle, partieImaginaire)
    • ou Complex(partieRéelle)
    • dans laquelle les deux parties réelles et imaginaires sont de simples expressions arithmétiques, combinant les quatre opérateurs +,-,*,/
  • Pour respecter les priorités, j'ai défini une expression comme étant une expression de type addition/soustraction, lequelles sont définies par un nombre ou bien une expression de type multiplication/division.
  • Un nombre est tout simplement une séquence de chiffres débutant par autre chose que 0, ou sinon le chiffre 0 lui-même
  • Dans chaque règle, j'ai définit des identifiants (sous la forme id:Règle), me permettant dans le bloc associé à la règle de définir comment interpréter la règle en fonction de ces identifiants.
Voilà, j'ai trouvé cet outil plutôt simple à utiliser.

Aucun commentaire:

Enregistrer un commentaire