MethodsDevelopmentTranslator
/
SyntaxAnalisator.cpp
711 строк · 18.4 Кб
1#include "SyntaxAnalisator.h"
2#include "function.h"
3
4SyntaxAnalisator::SyntaxAnalisator()
5{
6}
7
8
9SyntaxAnalisator::~SyntaxAnalisator()
10{
11}
12
13int numberString = 0;
14
15bool isIdentifierByCode(std::string token)
16{
17return token[0] == 'I' && isDigit((int)token[1]) == true ? true : false;
18}
19
20bool isOperationByCode(std::string token)
21{
22return token[0] == 'O' && isDigit((int)token[1]) == true ? true : false;
23}
24
25bool isSymbolConst(std::string token)
26{
27return token[0] == 'C' && isDigit((int)token[1]) == true ? true : false;
28}
29
30bool isNumberConstByCode(std::string token)
31{
32return token[0] == 'N' && isDigit((int)token[1]) == true ? true : false;
33}
34
35
36
37//std::string SyntaxAnalisator::readFromFileToString()
38//{
39// std::string code = "";
40// try
41// {
42// std::ifstream lexicalFile("./translator_file/lexical.txt");
43// if (lexicalFile.is_open())
44// {
45// std::string temp = "";
46// while (!lexicalFile.eof())
47// {
48// temp = "";
49// getline(lexicalFile, temp);
50// if (isSpaceInEndString(temp) == true)
51// temp.replace(temp.rfind(" "), 1, "");
52//
53// for (__int64 i = 0; i < temp.length(); i++)
54// {
55// if (isServiceSymbols((int)temp[i]) == false)
56// code += temp[i];
57// }
58// code += " ";
59//
60// }
61// return code;
62// }
63// else
64// {
65// System::Windows::Forms::MessageBox::Show("File don't open", "Error", System::Windows::Forms::MessageBoxButtons::OK, System::Windows::Forms::MessageBoxIcon::Error);
66// }
67// }
68// catch (const std::exception&)
69// {
70// System::Windows::Forms::MessageBox::Show("Problem with file to Syntaxanalisator", "Error",System::Windows::Forms::MessageBoxButtons::OK, System::Windows::Forms::MessageBoxIcon::Error);
71// }
72//
73//}
74
75std::string getToken(std::string& line)
76{
77std::string token = "";
78__int64 pos = line.find(' ');
79if (pos == std::string::npos)
80{
81token = line.substr(0, line.length());
82line = "";
83}
84else
85{
86token = line.substr(0, pos);
87line.erase(0, pos + 1);
88}
89return token;
90}
91
92
93bool SyntaxAnalisator::makeSyntaxAnalyze()
94{
95try
96{
97numberString = 0;
98std::ifstream lexicalFile("./translator_file/lexical.txt");
99if (lexicalFile.is_open())
100{
101std::string temp = "";
102int countInclude = 0, countFunction = 0;
103
104bool isDeclareFunction = false, isCycle = false, isIFElse = false, manyLineComment = false, mainFunctionChecked = false;
105while (!lexicalFile.eof())
106{
107std::string code = "";
108getline(lexicalFile, code);
109numberString++;
110if (code == "")
111continue;
112
113if (code.length() > 2 && isComment((int)code[0], (int)code[1]) && code.find("*/") == std::string::npos)
114manyLineComment = true;
115
116if (code.length() > 2 && (isComment((int)code[0], (int)code[1]) || isOneStringComment((int)code[0], (int)code[1])))
117continue;
118
119if (manyLineComment == true)
120{
121if (code.find("*/") != std::string::npos)
122manyLineComment = false;
123continue;
124}
125
126if (code.find("W8") == 0)
127{
128if (countInclude < this->countInclude)
129countInclude++;
130else
131{
132problemDetected("Detected #include excess!\n line:" + std::to_string(numberString));
133return false;
134}
135continue;
136}
137if (code.find("W11") == 0)
138{
139checkReturnExpression(code);
140continue;
141}
142if (code.find("W20") == 0)
143{
144code.erase(0, 7);
145if (isIdentifierByCode(code.substr(0, code.find(" "))) == false)
146{
147problemDetected("Method free accepts only identifier! \nline:" + std::to_string(numberString));
148return false;
149}
150code.erase(0, code.find(" ")+1);
151if (code.find("I") != std::string::npos)
152{
153problemDetected("Methods free accepts only one argument!\n line:" + std::to_string(numberString));
154return false;
155}
156continue;
157}
158
159if (code.find("W4") != std::string::npos && mainFunctionChecked == false)
160{
161mainFunctionChecked = true;
162countFunction++;
163isDeclareFunction = true;
164if (declareMainFunction(code) == false)
165{
166problemDetected("Problem with declare main function!\nline:" + std::to_string(numberString));
167return false;
168}
169continue;
170}
171else
172if (code.find("W4") != std::string::npos)
173{
174problemDetected("Detected excess main function!\n line:" + std::to_string(numberString));
175return false;
176}
177
178if (code.find("R5") == 0)
179{
180if (isDeclareFunction == false && isCycle == false && isIFElse == false)
181{
182problemDetected("Detected excess figure brackets!\n line: " + std::to_string(numberString));
183return false;
184}
185if (isDeclareFunction == true)
186{
187isDeclareFunction = false;
188if (countFunction > this->countFunction)
189{
190problemDetected("Detected excess function!\n line: " + std::to_string(numberString) +" all: " + std::to_string(this->countFunction) + " detected: " + std::to_string(countFunction));
191return false;
192}
193}
194
195if (isCycle == true)
196isCycle = false;
197if (isIFElse == true)
198isIFElse = false;
199continue;
200}
201
202if (code.find("R6") == 0)
203continue;
204__int64 pos = 0;
205std::string token = "";
206
207
208while ((pos = code.find(' ')) != std::string::npos || code.length() != 0)
209{
210token = getToken(code);
211
212if (isInclude(token) == true || token == "W9" || token == "W10")
213{
214problemDetected("Detected don't right declare/use function !\n line:" + std::to_string(numberString));
215return false;
216}
217
218if ((isTypeDeclarationByCode(token) == true || token=="W13") && is_declareFunction(code) == true)
219{
220countFunction++;
221isDeclareFunction = true;
222token = code.substr(0, 2);
223code.erase(0, 3);
224if (isIdentifierByCode(token) == true)
225{
226if (setArguments(code) == true)
227{
228continue;
229}
230else
231return false;
232}
233else
234{
235problemDetected("It is not identifier!\n line: " + std::to_string(numberString));
236return false;
237}
238}
239
240if (isTypeDeclarationByCode(token)==true && (code[0] == 'I' || code[0] == 'R'))
241{
242if (operators(code, "type") == false)
243return false;
244}
245else
246{
247if (isIFCondition(token) == true || token == "W7" == true || isELSECondition(token)==true)
248{
249if (operators(code, "condition") == false)
250return false;
251if (isIFCondition(token) == true || isELSECondition(token) == true)
252isIFElse = true;
253if (token == "W7")
254isCycle = true;
255continue;
256}
257if (token == "W12")
258{
259if (operators(code, "for") == false)
260return false;
261isCycle = true;
262continue;
263}
264if (isIdentifierByCode(token) == true)
265{
266if (operators(code, "Id") == false)
267return false;
268if (isIFElse == true)
269isIFElse = false;
270if (isCycle == true)
271isCycle = false;
272continue;
273}
274else
275{
276problemDetected("Detected unidentified symbol!\nline: " + std::to_string(numberString));
277return false;
278}
279}
280}
281}
282return true;
283}
284else
285{
286problemDetected("File don't open");
287return false;
288}
289}
290catch (const std::exception&)
291{
292System::Windows::Forms::MessageBox::Show("Problem with file to Syntaxanalisator", "Error",System::Windows::Forms::MessageBoxButtons::OK, System::Windows::Forms::MessageBoxIcon::Error);
293}
294
295
296}
297
298bool SyntaxAnalisator::declareMainFunction(std::string& main)
299{
300std::string token = getToken(main);
301if (isTypeDeclarationByCode(token) == false)
302return false;
303main.erase(0, 3);
304if (setArguments(main) == false)
305return false;
306return true;
307
308}
309
310
311bool SyntaxAnalisator::setArguments(std::string& code)
312{
313__int64 pos = 0;
314std::string fragment = code.substr(0, code.find("R4"));
315code.erase(0, code.find("R4") + 3);
316bool type_ident = false;
317while ((pos = fragment.find(' ')) != std::string::npos || fragment.length() != 0)
318{
319std::string token = getToken(fragment);
320if (token == "")
321continue;
322if (token.length() < 2)
323{
324problemDetected("Detected unindefined symbol (setArguments): " + token +"\nline: " + std::to_string(numberString));
325return false;
326}
327if (token == "W19")
328token += " " + getToken(fragment);
329
330if (token == "R8")
331continue;
332if (token == "R1")
333{
334std::string temp = fragment.substr(0, fragment.find("R2") - 1);
335if (operatorDeclareData(temp) == false)
336return false;
337
338fragment.erase(0, fragment.find("R2") + 2);
339continue;
340}
341if (isTypeDeclarationByCode(token) == true && type_ident == false)
342{
343type_ident = true;
344continue;
345}
346else
347if (isTypeDeclarationByCode(token) == true)
348{
349problemDetected("Expected identifer, but get type!\n line: " + std::to_string(numberString));
350return false;
351}
352
353if (isIdentifierByCode(token)==true && type_ident == true)
354{
355type_ident = false;
356continue;
357}
358else
359if (isIdentifierByCode(token)==true)
360{
361problemDetected("Expected type, but get identifier!\n line: " + std::to_string(numberString));
362return false;
363}
364}
365return true;
366}
367
368bool SyntaxAnalisator::is_declareFunction(std::string code)
369{
370__int64 pos = 0;
371int countSpace = 0;
372while ((pos = code.find(' ')) != std::string::npos || code.length() != 0)
373{
374std::string token = code.substr(0, pos);
375code.erase(0, pos + 1);
376countSpace++;
377if (token == "R3" && countSpace > 3)
378return false;
379else
380if (token == "R3" && countSpace == 2)
381return true;
382if (countSpace > 3)
383return false;
384}
385return false;
386}
387
388
389bool SyntaxAnalisator::operators(std::string& code, std::string token)
390{
391__int64 pos = 0;
392if (token == "type")
393return operatorDeclareData(code);
394if (token == "Id")
395return operatorEqual(code);
396if (token == "condition")
397return operatorCondition(code);
398if (token == "for")
399return operatorFor(code);
400return false;
401
402}
403
404bool SyntaxAnalisator::operatorCondition(std::string& code)
405{
406code.erase(0, 3);
407if (parseExpression(code, true) == false)
408return false;
409return true;
410}
411
412bool SyntaxAnalisator::operatorFor(std::string& code)
413{
414code.erase(0, 3);
415std::string temp = "";
416if (isTypeDeclarationByCode(code.substr(0, code.find(" "))) == true)
417{
418code.erase(0, code.find(" ")+1);
419temp = code.substr(0, code.find("R7") + 2);
420code.erase(0, code.find("R7") + 3);
421if (operatorEqual(temp) == false)
422return false;
423}
424else
425{
426problemDetected("Expected type, but get "+ code.substr(0, code.find(" ")) +"!\n line: " + std::to_string(numberString));
427return false;
428}
429temp = code.substr(0, code.find("R7") + 2);
430code.erase(0, code.find("R7") + 3);
431if (parseExpression(temp, true) == false)
432return false;
433temp = code.substr(0, code.find("R4")-1);
434code = "";
435if (operatorEqual(temp) == false)
436return false;
437
438return true;
439}
440
441bool SyntaxAnalisator::operatorDeclareData(std::string& code)
442{
443if (code.find("O5") != std::string::npos)
444if (operatorEqual(code) == false)
445return false;
446else
447return true;
448
449__int64 pos = 0;
450std::string token = "";
451bool ident_comma = false;
452while ((pos = code.find(' ')) != std::string::npos || code.length() != 0)
453{
454token = getToken(code);
455if (token == "")
456continue;
457if (token.length() < 2)
458{
459problemDetected("Detected unindefined symbol (operatorDeclareData): " + token + "\nline: " + std::to_string(numberString));
460return false;
461}
462if (token == "R7" && ident_comma == true)
463break;
464else
465if (token == "R7")
466{
467problemDetected("Before similcon detected ','!\n line: " + std::to_string(numberString));
468return false;
469}
470
471if (isIdentifierByCode(token) == true && ident_comma == false)
472{
473ident_comma = true;
474continue;
475}
476else
477if (isIdentifierByCode(token) == true)
478{
479problemDetected("Expected ',', but get type !\n line: " + std::to_string(numberString));
480return false;
481}
482
483if (token == "R8" && ident_comma == true)
484{
485ident_comma = false;
486continue;
487}
488else
489if (token == "R8")
490{
491problemDetected("Expected type, but get ',' !\n line: " + std::to_string(numberString));
492return false;
493}
494
495}
496return true;
497
498}
499
500bool SyntaxAnalisator::operatorEqual(std::string& code)
501{
502__int64 pos = 0;
503std::string token = "";
504
505while ((pos = code.find(' ')) != std::string::npos || code.length() != 0)
506{
507std::string fragmentBeforeComma = "";
508__int64 posComma = code.find("R8");
509if (posComma != std::string::npos && code.find("O5", posComma) != std::string::npos)
510{
511fragmentBeforeComma = code.substr(0, posComma);
512code.erase(0, posComma + 1);
513if(parseExpression(fragmentBeforeComma,false)==false)
514return false;
515
516if (isTypeDeclarationByCode(code.substr(0, code.find(" "))) == true || isOperationByCode(code.substr(0, code.find(" "))) == true || isSymbolConst(code.substr(0, code.find(" "))) == true
517|| isCloseAnyBracket(code.substr(0, 2)) == true || isOpenAnyBracket(code.substr(0, 2)) == true)
518{
519problemDetected("Get " + code.substr(0, code.find(" ")) + " expected identifier\nline: " + std::to_string(numberString));
520return false;
521}
522continue;
523}
524
525if (parseExpression(code, false) == false)
526return false;
527else
528return true;
529
530
531}
532return true;
533}
534
535void pushStackAndPop(std::stack<std::string>& stack,std::string token)
536{
537stack.pop();
538stack.push(token);
539}
540
541bool SyntaxAnalisator::parseExpression(std::string& fragment,bool condition)
542{
543std::stack<std::string> temp_stack;
544__int64 pos = 0;
545std::string token = "";
546//<typeFunction> (*pFunction)(<type_arg>) = NULL;
547//pFunction = &isIdentifierByCode;
548//arg function -> <typeFunction> (*pFunction)(<type_arg>)
549while ((pos = fragment.find(' ')) != std::string::npos || fragment.length() != 0)
550{
551token = getToken(fragment);
552if (token == "")
553continue;
554if (token.length() < 2)
555{
556problemDetected("Detected unindefined symbol (expression): " + token + "\nline: " + std::to_string(numberString));
557return false;
558}
559if (token == "R1")
560{
561std::string temp = fragment.substr(0, fragment.find("R2") - 1);
562if (operatorDeclareData(temp) == false)
563return false;
564
565fragment.erase(0, fragment.find("R2") + 2);
566continue;
567}
568if (temp_stack.size() == 0)
569{
570if (condition == true && (token[0]=='I' || token[0]=='N' || token[0]=='C'))
571temp_stack.push(token);
572else
573if (condition == true)
574{
575problemDetected("It is if/while/else expected next I_/N_/C_, but get: " + token + "\nline: " + std::to_string(numberString));
576return false;
577}
578else
579temp_stack.push(token);
580continue;
581}
582if (token == "R7" && condition == false)
583{
584if (isOperationByCode(temp_stack.top()) == true && (temp_stack.top()!= "O20" && temp_stack.top() != "O19"))
585{
586problemDetected("Before ; get: " + temp_stack.top() + "\nline: " + std::to_string(numberString));
587return false;
588}
589return true;
590}
591if (condition == true && token == "R4" && fragment.length() == 0)
592return true;
593if (condition == true)
594{
595if (breachOfCodition(token,temp_stack)==true)
596{
597problemDetected("It is if/while/else expected in stack I_/N_/C_, but get: " + temp_stack.top() + "\nline: " + std::to_string(numberString));
598return false;
599}
600
601}
602else
603{
604std::string nextCode = fragment.substr(0, fragment.find(" "));
605if (nextCode != "R7")
606{
607if (breachOfExpressionWithNumberConst(token, temp_stack, nextCode) == true )
608{
609problemDetected("there is problem with expression " + token + " expected operation, but get: before " + temp_stack.top() + "/ after " + nextCode + "\nline: " + std::to_string(numberString));
610return false;
611}
612}
613
614}
615
616
617
618if (isOpenAnyBracket(token) == true && isCloseAnyBracket(temp_stack.top()) == false)
619{
620pushStackAndPop(temp_stack, token);
621continue;
622}
623else
624if (isOpenAnyBracket(token) == true)
625{
626problemDetected("Detected )(\nline: " + std::to_string(numberString));
627return false;
628}
629
630if (isCloseAnyBracket(token) == true && temp_stack.top() != "R7")
631{
632pushStackAndPop(temp_stack, token);
633continue;
634}
635else
636if (isCloseAnyBracket(token) == true)
637{
638problemDetected("Detected ;) in expression: \nline: " + std::to_string(numberString));
639return false;
640}
641
642
643if (isRepeatWordByCode(&isIdentifierByCode, temp_stack, token) == 0)
644return false;
645else
646{
647if (isRepeatWordByCode(&isNumberConstByCode, temp_stack, token) == 0)
648return false;
649else
650{
651if (isRepeatWordByCode(&isSymbolConst, temp_stack, token) == 0)
652return false;
653else
654{
655if (isRepeatWordByCode(&isOperationByCode, temp_stack, token) == 0)
656return false;
657else
658pushStackAndPop(temp_stack, token);
659}
660}
661}
662if (positionTypeConversion(fragment) == 0)
663{
664pushStackAndPop(temp_stack, fragment.substr(0, 2));
665pushStackAndPop(temp_stack, fragment.substr(3, fragment.find("R4") - 2));
666pushStackAndPop(temp_stack, fragment.substr(fragment.find("R4"), 2));
667fragment.erase(0, 10);
668//token = getToken(fragment);
669}
670
671}
672
673return true;
674}
675
676bool SyntaxAnalisator::breachOfCodition(std::string const& token,std::stack<std::string>const& temp_stack)
677{
678return (isOperationByCode(token) == true && (isIdentifierByCode(temp_stack.top()) == false && isNumberConstByCode(temp_stack.top()) == false && isSymbolConst(temp_stack.top()) == false && isCloseAnyBracket(temp_stack.top()) == false)) || ((isIdentifierByCode(token) == true || isNumberConstByCode(token) == true || isSymbolConst(token) == true) && isOperationByCode(temp_stack.top()) == false);
679}
680bool SyntaxAnalisator::breachOfExpressionWithNumberConst(std::string const& token, std::stack<std::string>const& temp_stack,std::string nextCommand)
681{
682bool isWordConst = (isNumberConstByCode(token) == true || isSymbolConst(token) == true);
683if (isWordConst == false)
684return false;
685if (temp_stack.top() == "R8" || nextCommand == "R8")
686return false;
687bool operation_word = isOperationByCode(temp_stack.top()) == true;
688bool word_operation = isOperationByCode(nextCommand) == true;
689bool bracket_word = temp_stack.top() == "R3";
690bool word_bracket = nextCommand == "R4";
691bool breach = !((operation_word == true && word_operation == true) || (bracket_word == true && word_bracket == true));
692return breach == true;
693}
694
695int SyntaxAnalisator::isRepeatWordByCode(bool (*pFunctWordByCode)(std::string), std::stack<std::string>& temp_stack, std::string token)
696{
697if ((*pFunctWordByCode)(token) == true && (*pFunctWordByCode)(temp_stack.top()) == true)
698{
699problemDetected("Detected repeat word! "+token+ " stack: " + temp_stack.top() + "\nline:"+ std::to_string(numberString));
700return false;
701}
702return 1;
703}
704
705bool SyntaxAnalisator::checkReturnExpression(std::string& expr)
706{
707expr.erase(0, 3);
708if (parseExpression(expr,false) == false)
709return false;
710return true;
711}