1+ #include " Parser.h"
2+
3+ namespace FPL {
4+ Parser::Parser () {
5+ mTypes [" vide" ] = Type (" vide" , VOID);
6+ mTypes [" entier" ] = Type (" entier" , INT);
7+ mTypes [" decimal" ] = Type (" decimal" , DOUBLE);
8+ mTypes [" texte" ] = Type (" texte" , STRING);
9+ }
10+
11+ bool Parser::FunctionChecker () {
12+ auto parseStart = mCurrentToken ; // std::vector<Token>::iterator
13+ auto PeutEtreInstruction = CheckerIdentifiant ();
14+ if (PeutEtreInstruction.has_value ()) {
15+ // On a une instruction
16+ if (PeutEtreInstruction->mText == " definir" ) { // On vérifie si l'instruction est une fonction
17+ auto PeutEtreNom = CheckerIdentifiant ();
18+ if (PeutEtreNom.has_value ()) {
19+ // On a le nom d'une fonction.
20+ if (CheckerOperateur (" (" ).has_value ()) {
21+ // On a surement une fonction finie !
22+
23+ FonctionDefinition fonction;
24+ fonction.FonctionName = PeutEtreNom->mText ;
25+
26+ while (CheckerOperateur (" )" ) == std::nullopt ) {
27+ auto type = CheckerType ();
28+
29+ // Si aucun paramètre ou l'utilisateur a utilisé l'argument 'vide' ou juste fermer.
30+ if (type->mType == VOID) { break ; }
31+
32+ if (!type.has_value () || type == std::nullopt ) {
33+ throw std::runtime_error (" Vous devez spécifier un type d'argument." );
34+ }
35+
36+ // Ajout de l'argument...
37+ auto variableName = CheckerIdentifiant ();
38+ if (!variableName.has_value ()) {
39+ throw std::runtime_error (" Vous devez spécifier un nom unique à l'argument." );
40+ }
41+ ArgumentDefinition param;
42+ param.ArgType .mName = type->mName ;
43+ param.ArgType .mType = type->mType ;
44+ param.ArgName = variableName->mText ;
45+ fonction.ArgsFonction .push_back (param);
46+
47+ if (CheckerOperateur (" )" ).has_value ()) {
48+ break ;
49+ }
50+ if (!CheckerOperateur (" ," ).has_value ()) {
51+ throw std::runtime_error (
52+ " Vous devez utiliser la ',' pour separer les arguments de la fonction." );
53+ }
54+ }
55+
56+ mFonctions [fonction.FonctionName ] = fonction;
57+
58+ // On récupère le code entre les {} :
59+
60+ if (CheckerOperateur (" {" )) {
61+ while (!CheckerOperateur (" }" ).has_value ()) {
62+ fonction.FonctionContent .push_back (mCurrentToken ->mText );
63+ ++mCurrentToken ;
64+
65+ if (CheckerOperateur (" }" ).has_value ()) {
66+ break ;
67+ }
68+ }
69+
70+ }
71+
72+ return true ;
73+ } else {
74+ mCurrentToken = parseStart;
75+ std::cerr
76+ << " Vous devez ouvrir les parenthèses pour ajouter des paramètres si vous le souhaitez."
77+ << std::endl;
78+ }
79+ } else {
80+ mCurrentToken = parseStart;
81+ std::cerr << " Vous devez donner un nom à votre fonction." << std::endl;
82+ }
83+ } else {
84+ mCurrentToken = parseStart;
85+ }
86+ }
87+ return false ;
88+ }
89+
90+
91+ bool Parser::PrintStat () {
92+ auto parseStart = mCurrentToken ; // std::vector<Token>::iterator
93+ auto PeutEtreInstruction = CheckerIdentifiant ();
94+ if (PeutEtreInstruction.has_value ()) {
95+ if (PeutEtreInstruction->mText == " envoyer" ) {
96+ auto ChaineEnter = CheckerChaineLitteral ();
97+ if (ChaineEnter.has_value ()) {
98+ std::string printContent = ChaineEnter->mText ;
99+ std::replace (printContent.begin (), printContent.end (), ' "' , ' ' );
100+ std::cout << printContent;
101+ std::cout << std::endl;
102+ return true ;
103+ } else {
104+ std::cerr
105+ << " Vous devez mettre des \" pour ouvrir et fermer l'instruction que si le type est texte."
106+ << std::endl;
107+ mCurrentToken = parseStart;
108+ }
109+ }
110+ }
111+ return false ;
112+ }
113+
114+ bool Parser::VariableDeclaration () {
115+ auto parseStart = mCurrentToken ; // std::vector<Token>::iterator
116+ auto PeutEtreInstruction = CheckerIdentifiant ();
117+ if (PeutEtreInstruction.has_value () && PeutEtreInstruction->mText == " variable" ) {
118+ auto pType = CheckerType ();
119+ if (pType.has_value ()) {
120+ if (pType->mType == VOID) {
121+ std::cerr << " Le type 'vide' n'est pas possible pour une variable." << std::endl;
122+ mCurrentToken = parseStart;
123+ }
124+
125+ auto pName = CheckerIdentifiant ();
126+ if (pName.has_value ()) {
127+
128+ if (CheckerOperateur (" -" ).has_value ()) {
129+ if (CheckerOperateur (" >" ).has_value ()) {
130+ auto pValue = CheckerValue ();
131+ if (pValue.has_value ()) {
132+ // VariableDefinition variable(pName->mText, pType->mName, pType->mType);
133+ VariableDefinition variable;
134+ variable.VariableName = pName->mText ;
135+ variable.VariableType = Type (pType->mName , pType->mType );
136+ variable.GiveValue (mCurrentToken ->mText );
137+
138+ mVariables [variable.VariableName ] = variable;
139+ return true ;
140+ } else {
141+ throw std::runtime_error (" Vous devez donner une valeur a votre variable." );
142+ }
143+ } else {
144+ throw std::runtime_error (" Pour donner la valeur à votre variable, merci d'utiliser '->'." );
145+ }
146+ } else {
147+ throw std::runtime_error (" Pour donner la valeur à votre variable, merci d'utiliser '->'." );
148+ }
149+ } else {
150+ std::cerr << " Vous devez donner un nom à votre variable." << std::endl;
151+ mCurrentToken = parseStart;
152+ }
153+ } else {
154+ std::cerr << " Vous devez mettre le type de votre variable." << std::endl;
155+ mCurrentToken = parseStart;
156+ }
157+ }
158+ return false ;
159+ }
160+
161+
162+ void Parser::parse (std::vector<Token> &tokens) {
163+ mEndToken = tokens.end ();
164+ mCurrentToken = tokens.begin ();
165+
166+ while (mCurrentToken != mEndToken ) { // Tant que tout le fichier n'est pas parcouru et qu'on n'a pas analysé tous les éléments.
167+ if (FunctionChecker ()) {
168+
169+ }
170+
171+ if (PrintStat ()) {
172+
173+ }
174+
175+ if (VariableDeclaration ()) {
176+
177+ } else {
178+ if (mCurrentToken ->mText .empty ()) {
179+ continue ;
180+ }
181+ std::cerr << " Identifier inconnu : " << Parser::mCurrentToken ->mText << std::endl;
182+ ++mCurrentToken ;
183+ }
184+ }
185+ }
186+
187+ std::optional<Token> Parser::CheckerChaineLitteral (const std::string &name) {
188+ if (mCurrentToken == mEndToken ) { return std::nullopt ; }
189+ if (mCurrentToken ->mType != CHAINE_LITERAL) { return std::nullopt ; }
190+ if (mCurrentToken ->mText != name && !name.empty ()) { return std::nullopt ; }
191+
192+ auto returnToken = mCurrentToken ;
193+ ++mCurrentToken ;
194+ return *returnToken;
195+ }
196+
197+ std::optional<Token> Parser::CheckerIdentifiant (const std::string &name) {
198+ if (mCurrentToken == mEndToken ) { return std::nullopt ; }
199+ if (mCurrentToken ->mType != IDENTIFIANT) { return std::nullopt ; }
200+ if (mCurrentToken ->mText != name && !name.empty ()) { return std::nullopt ; }
201+
202+ auto returnToken = mCurrentToken ;
203+ ++mCurrentToken ;
204+ return *returnToken;
205+ }
206+
207+ std::optional<Token> Parser::CheckerOperateur (const std::string &name) {
208+ if (mCurrentToken == mEndToken ) { return std::nullopt ; }
209+ if (mCurrentToken ->mType != OPERATEUR) { return std::nullopt ; }
210+ if (mCurrentToken ->mText != name && !name.empty ()) { return std::nullopt ; }
211+ // On vérifie s'il est présent, si c'est un OPERATEUR et que c'est le bon nom.
212+
213+ auto returnToken = mCurrentToken ; // std::vector<Token>::iterator
214+ ++mCurrentToken ;
215+ return *returnToken; // On donne l'opérateur
216+ }
217+
218+ std::optional<Type> Parser::CheckerType (const std::string &name) {
219+ auto possibleType = CheckerIdentifiant ();
220+ if (!possibleType.has_value ()) { return std::nullopt ; }
221+
222+ auto foundType = mTypes .find (possibleType->mText );
223+ if (foundType == mTypes .end ()) {
224+ --mCurrentToken ;
225+ return std::nullopt ;
226+ }
227+
228+ return foundType->second ;
229+ }
230+
231+ std::optional<Statement> Parser::CheckerValue ()
232+ {
233+ std::optional<Statement> res;
234+ if (mCurrentToken ->mType == DECIMAL_LITERAL)
235+ {
236+ Statement doubleLitteralStatement (StatementKind::LITTERAL, mCurrentToken ->mText , Type (" decimal" , DOUBLE));
237+ res = doubleLitteralStatement;
238+ ++mCurrentToken ;
239+ }
240+ else if (mCurrentToken ->mType == ENTIER_LITERAL)
241+ {
242+ Statement integerLitteralStatement (StatementKind::LITTERAL, mCurrentToken ->mText , Type (" entier" , INT));
243+ res = integerLitteralStatement;
244+ ++mCurrentToken ;
245+ }
246+ else if (mCurrentToken ->mType == CHAINE_LITERAL)
247+ {
248+ Statement stringLitteralStatement (StatementKind::LITTERAL, mCurrentToken ->mText , Type (" text" , STRING));
249+ res = stringLitteralStatement;
250+ ++mCurrentToken ;
251+ } else {
252+ return std::nullopt ;
253+ }
254+
255+ return res;
256+ }
257+
258+
259+ void Parser::DebugPrint () const {
260+ for (auto &funcPair: mFonctions ) {
261+ for (auto &e: funcPair.second .FonctionContent ) {
262+ std::cout << e << std::endl;
263+ }
264+ }
265+ }
266+ }
0 commit comments