MethodsDevelopmentTranslator

Форк
0
/
SyntaxAnalisator.cpp 
711 строк · 18.4 Кб
1
#include "SyntaxAnalisator.h"
2
#include "function.h"
3

4
SyntaxAnalisator::SyntaxAnalisator()
5
{
6
}
7

8

9
SyntaxAnalisator::~SyntaxAnalisator()
10
{
11
}
12

13
int numberString = 0;
14

15
bool isIdentifierByCode(std::string token)
16
{
17
	return token[0] == 'I' && isDigit((int)token[1]) == true ? true : false;
18
}
19

20
bool isOperationByCode(std::string token)
21
{
22
	return token[0] == 'O' && isDigit((int)token[1]) == true ? true : false;
23
}
24

25
bool isSymbolConst(std::string token)
26
{
27
	return token[0] == 'C' && isDigit((int)token[1]) == true ? true : false;
28
}
29

30
bool isNumberConstByCode(std::string token)
31
{
32
	return 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

75
std::string getToken(std::string& line)
76
{
77
	std::string token = "";
78
	__int64 pos = line.find(' ');
79
	if (pos == std::string::npos)
80
	{
81
		token = line.substr(0, line.length());
82
		line = "";
83
	}
84
	else
85
	{
86
		token = line.substr(0, pos);
87
		line.erase(0, pos + 1);
88
	}
89
	return token;
90
}
91

92

93
bool SyntaxAnalisator::makeSyntaxAnalyze()
94
{
95
	try
96
	{
97
		numberString = 0;
98
		std::ifstream lexicalFile("./translator_file/lexical.txt");
99
		if (lexicalFile.is_open())
100
		{
101
			std::string temp = "";
102
			int countInclude = 0, countFunction = 0;
103
			
104
			bool isDeclareFunction = false, isCycle = false, isIFElse = false, manyLineComment = false, mainFunctionChecked = false;
105
			while (!lexicalFile.eof())
106
			{
107
				std::string code = "";
108
				getline(lexicalFile, code);
109
				numberString++;
110
				if (code == "")
111
					continue;
112

113
				if (code.length() > 2 && isComment((int)code[0], (int)code[1]) && code.find("*/") == std::string::npos)
114
					manyLineComment = true;
115

116
				if (code.length() > 2 && (isComment((int)code[0], (int)code[1]) || isOneStringComment((int)code[0], (int)code[1])))
117
					continue;
118

119
				if (manyLineComment == true)
120
				{
121
					if (code.find("*/") != std::string::npos)
122
						manyLineComment = false;
123
					continue;
124
				}
125

126
				if (code.find("W8") == 0)
127
				{
128
					if (countInclude < this->countInclude)
129
						countInclude++;
130
					else
131
					{
132
						problemDetected("Detected #include excess!\n line:" + std::to_string(numberString));
133
						return false;
134
					}
135
					continue;
136
				}
137
				if (code.find("W11") == 0)
138
				{
139
					checkReturnExpression(code);
140
					continue;
141
				}
142
				if (code.find("W20") == 0)
143
				{
144
					code.erase(0, 7);
145
					if (isIdentifierByCode(code.substr(0, code.find(" "))) == false)
146
					{
147
						problemDetected("Method free accepts only identifier! \nline:" + std::to_string(numberString));
148
						return false;
149
					}
150
					code.erase(0, code.find(" ")+1);
151
					if (code.find("I") != std::string::npos)
152
					{
153
						problemDetected("Methods free accepts only one argument!\n line:" + std::to_string(numberString));
154
						return false;
155
					}
156
					continue;
157
				}
158

159
				if (code.find("W4") != std::string::npos && mainFunctionChecked == false)
160
				{
161
					mainFunctionChecked = true;
162
					countFunction++;
163
					isDeclareFunction = true;
164
					if (declareMainFunction(code) == false)
165
					{
166
						problemDetected("Problem with declare main function!\nline:" + std::to_string(numberString));
167
						return false;
168
					}
169
					continue;
170
				}
171
				else
172
					if (code.find("W4") != std::string::npos)
173
					{
174
						problemDetected("Detected excess main function!\n line:" + std::to_string(numberString));
175
						return false;
176
					}
177

178
				if (code.find("R5") == 0)
179
				{
180
					if (isDeclareFunction == false && isCycle == false && isIFElse == false)
181
					{
182
						problemDetected("Detected excess figure brackets!\n line: " + std::to_string(numberString));
183
						return false;
184
					}
185
					if (isDeclareFunction == true)
186
					{
187
						isDeclareFunction = false;
188
						if (countFunction > this->countFunction)
189
						{
190
							problemDetected("Detected excess function!\n line: " + std::to_string(numberString) +" all: " + std::to_string(this->countFunction) + " detected: " + std::to_string(countFunction));
191
							return false;
192
						}
193
					}
194
					
195
					if (isCycle == true)
196
						isCycle = false;
197
					if (isIFElse == true)
198
						isIFElse = false;
199
					continue;
200
				}
201

202
				if (code.find("R6") == 0)
203
					continue;
204
				__int64 pos = 0;
205
				std::string token = "";
206
				
207
				
208
				while ((pos = code.find(' ')) != std::string::npos || code.length() != 0)
209
				{
210
					token = getToken(code);
211

212
					if (isInclude(token) == true || token == "W9" || token == "W10")
213
					{
214
						problemDetected("Detected don't right declare/use function !\n line:" + std::to_string(numberString));
215
						return false;
216
					}
217
	
218
					if ((isTypeDeclarationByCode(token) == true || token=="W13") && is_declareFunction(code) == true)
219
					{
220
						countFunction++;
221
						isDeclareFunction = true;
222
						token = code.substr(0, 2);
223
						code.erase(0, 3);
224
						if (isIdentifierByCode(token) == true)
225
						{
226
							if (setArguments(code) == true)
227
							{
228
								continue;
229
							}
230
							else
231
								return false;
232
						}
233
						else
234
						{
235
							problemDetected("It is not identifier!\n line: " + std::to_string(numberString));
236
							return false;
237
						}
238
					}
239

240
					if (isTypeDeclarationByCode(token)==true && (code[0] == 'I' || code[0] == 'R'))
241
					{
242
						if (operators(code, "type") == false)
243
							return false;
244
					}
245
					else
246
					{
247
						if (isIFCondition(token) == true || token == "W7" == true || isELSECondition(token)==true)
248
						{
249
							if (operators(code, "condition") == false)
250
								return false;
251
							if (isIFCondition(token) == true || isELSECondition(token) == true)
252
								isIFElse = true;
253
							if (token == "W7")
254
								isCycle = true;
255
							continue;
256
						}
257
						if (token == "W12")
258
						{
259
							if (operators(code, "for") == false)
260
								return false;
261
							isCycle = true;
262
							continue;
263
						}
264
						if (isIdentifierByCode(token) == true)
265
						{
266
							if (operators(code, "Id") == false)
267
								return false;
268
							if (isIFElse == true)
269
								isIFElse = false;
270
							if (isCycle == true)
271
								isCycle = false;
272
							continue;
273
						}
274
						else
275
						{
276
							problemDetected("Detected unidentified symbol!\nline: " + std::to_string(numberString));
277
							return false;
278
						}
279
					}
280
				}
281
			}
282
			return true;
283
		}
284
		else
285
		{
286
			problemDetected("File don't open");
287
			return false;
288
		}
289
	}
290
	catch (const std::exception&)
291
	{
292
		System::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

298
bool SyntaxAnalisator::declareMainFunction(std::string& main)
299
{
300
	std::string token = getToken(main);
301
	if (isTypeDeclarationByCode(token) == false)
302
		return false;
303
	main.erase(0, 3);
304
	if (setArguments(main) == false)
305
		return false;
306
	return true;
307

308
}
309

310

311
bool SyntaxAnalisator::setArguments(std::string& code)
312
{
313
	__int64 pos = 0;
314
	std::string fragment = code.substr(0, code.find("R4"));
315
	code.erase(0, code.find("R4") + 3);
316
	bool type_ident = false;
317
	while ((pos = fragment.find(' ')) != std::string::npos || fragment.length() != 0)
318
	{
319
		std::string token = getToken(fragment);
320
		if (token == "")
321
			continue;
322
		if (token.length() < 2)
323
		{
324
			problemDetected("Detected unindefined symbol (setArguments): " + token +"\nline: " + std::to_string(numberString));
325
			return false;
326
		}
327
		if (token == "W19")
328
			token += " " + getToken(fragment);
329
		
330
		if (token == "R8")
331
			continue;
332
		if (token == "R1")
333
		{
334
			std::string temp = fragment.substr(0, fragment.find("R2") - 1);
335
			if (operatorDeclareData(temp) == false)
336
				return false;
337

338
			fragment.erase(0, fragment.find("R2") + 2);
339
			continue;
340
		}
341
		if (isTypeDeclarationByCode(token) == true && type_ident == false)
342
		{
343
			type_ident = true;
344
			continue;
345
		}
346
		else
347
			if (isTypeDeclarationByCode(token) == true)
348
			{
349
				problemDetected("Expected identifer, but get type!\n line: " + std::to_string(numberString));
350
				return false;
351
			}
352

353
		if (isIdentifierByCode(token)==true && type_ident == true)
354
		{
355
			type_ident = false;
356
			continue;
357
		}
358
		else
359
			if (isIdentifierByCode(token)==true)
360
			{
361
				problemDetected("Expected type, but get identifier!\n line: " + std::to_string(numberString));
362
				return false;
363
			}
364
	}
365
	return true;
366
}
367

368
bool SyntaxAnalisator::is_declareFunction(std::string code)
369
{
370
	__int64 pos = 0;
371
	int countSpace = 0;
372
	while ((pos = code.find(' ')) != std::string::npos || code.length() != 0)
373
	{
374
		std::string token = code.substr(0, pos);
375
		code.erase(0, pos + 1);
376
		countSpace++;
377
		if (token == "R3" && countSpace > 3)
378
			return false;
379
		else
380
			if (token == "R3" && countSpace == 2)
381
				return true;
382
		if (countSpace > 3)
383
			return false;
384
	}
385
	return false;
386
}
387

388

389
bool SyntaxAnalisator::operators(std::string& code, std::string token)
390
{
391
	__int64 pos = 0;
392
	if (token == "type")
393
		return operatorDeclareData(code);
394
	if (token == "Id")
395
		return operatorEqual(code);
396
	if (token == "condition")
397
		return operatorCondition(code);
398
	if (token == "for")
399
		return operatorFor(code);
400
	return false;
401

402
}
403

404
bool SyntaxAnalisator::operatorCondition(std::string& code)
405
{
406
	code.erase(0, 3);
407
	if (parseExpression(code, true) == false)
408
		return false;
409
	return true;
410
}
411

412
bool SyntaxAnalisator::operatorFor(std::string& code)
413
{
414
	code.erase(0, 3);
415
	std::string temp = "";
416
	if (isTypeDeclarationByCode(code.substr(0, code.find(" "))) == true)
417
	{
418
		code.erase(0, code.find(" ")+1);
419
		temp = code.substr(0, code.find("R7") + 2);
420
		code.erase(0, code.find("R7") + 3);
421
		if (operatorEqual(temp) == false)
422
			return false;
423
	}
424
	else
425
	{
426
		problemDetected("Expected type, but get "+ code.substr(0, code.find(" ")) +"!\n line: " + std::to_string(numberString));
427
		return false;
428
	}
429
	temp = code.substr(0, code.find("R7") + 2);
430
	code.erase(0, code.find("R7") + 3);
431
	if (parseExpression(temp, true) == false)
432
		return false;
433
	temp = code.substr(0, code.find("R4")-1);
434
	code = "";
435
	if (operatorEqual(temp) == false)
436
		return false;
437

438
	return true;
439
}
440

441
bool SyntaxAnalisator::operatorDeclareData(std::string& code)
442
{
443
	if (code.find("O5") != std::string::npos)
444
		if (operatorEqual(code) == false)
445
			return false;
446
		else
447
			return true;
448

449
	__int64 pos = 0;
450
	std::string token = "";
451
	bool ident_comma = false;
452
	while ((pos = code.find(' ')) != std::string::npos || code.length() != 0)
453
	{
454
		token = getToken(code);
455
		if (token == "")
456
			continue;
457
		if (token.length() < 2)
458
		{
459
			problemDetected("Detected unindefined symbol (operatorDeclareData): " + token + "\nline: " + std::to_string(numberString));
460
			return false;
461
		}
462
		if (token == "R7" && ident_comma == true)
463
			break;
464
		else
465
			if (token == "R7")
466
			{
467
				problemDetected("Before similcon detected ','!\n line: " + std::to_string(numberString));
468
				return false;
469
			}
470

471
		if (isIdentifierByCode(token) == true && ident_comma == false)
472
		{
473
			ident_comma = true;
474
			continue;
475
		}
476
		else
477
			if (isIdentifierByCode(token) == true)
478
			{
479
				problemDetected("Expected ',', but get type !\n line: " + std::to_string(numberString));
480
				return false;
481
			}
482
		
483
		if (token == "R8" && ident_comma == true)
484
		{
485
			ident_comma = false;
486
			continue;
487
		}
488
		else
489
			if (token == "R8")
490
			{
491
				problemDetected("Expected type, but get ',' !\n line: " + std::to_string(numberString));
492
				return false;
493
			}
494
		
495
	}
496
	return true;
497

498
}
499

500
bool SyntaxAnalisator::operatorEqual(std::string& code)
501
{
502
	__int64 pos = 0;
503
	std::string token = "";
504
	
505
	while ((pos = code.find(' ')) != std::string::npos || code.length() != 0)
506
	{
507
		std::string fragmentBeforeComma = "";
508
		__int64 posComma = code.find("R8"); 
509
		if (posComma != std::string::npos && code.find("O5", posComma) != std::string::npos)
510
		{
511
			fragmentBeforeComma = code.substr(0, posComma);
512
			code.erase(0, posComma + 1);
513
			if(parseExpression(fragmentBeforeComma,false)==false)
514
				return false;
515
			
516
			if (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
			{
519
				problemDetected("Get " + code.substr(0, code.find(" ")) + " expected identifier\nline: " + std::to_string(numberString));
520
				return false;
521
			}
522
			continue;
523
		}
524

525
		if (parseExpression(code, false) == false)
526
			return false;
527
		else
528
			return true;
529
		
530

531
	}
532
	return true;
533
}
534

535
void pushStackAndPop(std::stack<std::string>& stack,std::string token)
536
{
537
	stack.pop();
538
	stack.push(token);
539
}
540

541
bool SyntaxAnalisator::parseExpression(std::string& fragment,bool condition)
542
{
543
	std::stack<std::string> temp_stack;
544
	__int64 pos = 0;
545
	std::string token = "";
546
	//<typeFunction> (*pFunction)(<type_arg>) = NULL;
547
	//pFunction = &isIdentifierByCode;
548
	//arg function -> <typeFunction> (*pFunction)(<type_arg>)
549
	while ((pos = fragment.find(' ')) != std::string::npos || fragment.length() != 0)
550
	{
551
		token = getToken(fragment);
552
		if (token == "")
553
			continue;
554
		if (token.length() < 2)
555
		{
556
			problemDetected("Detected unindefined symbol (expression): " + token + "\nline: " + std::to_string(numberString));
557
			return false;
558
		}
559
		if (token == "R1")
560
		{
561
			std::string temp = fragment.substr(0, fragment.find("R2") - 1);
562
			if (operatorDeclareData(temp) == false)
563
				return false;
564

565
			fragment.erase(0, fragment.find("R2") + 2);
566
			continue;
567
		}
568
		if (temp_stack.size() == 0)
569
		{
570
			if (condition == true && (token[0]=='I' || token[0]=='N' || token[0]=='C'))
571
				temp_stack.push(token);
572
			else
573
				if (condition == true)
574
				{
575
					problemDetected("It is if/while/else expected next I_/N_/C_, but get: " + token + "\nline: " + std::to_string(numberString));
576
					return false;
577
				}
578
				else
579
					temp_stack.push(token);
580
			continue;
581
		}
582
		if (token == "R7" && condition == false)
583
		{
584
			if (isOperationByCode(temp_stack.top()) == true && (temp_stack.top()!= "O20" && temp_stack.top() != "O19"))
585
			{
586
				problemDetected("Before ; get: " + temp_stack.top() + "\nline: " + std::to_string(numberString));
587
				return false;
588
			}
589
			return true;
590
		}
591
		if (condition == true && token == "R4" && fragment.length() == 0)
592
			return true;
593
		if (condition == true)
594
		{
595
			if (breachOfCodition(token,temp_stack)==true)
596
			{
597
				problemDetected("It is if/while/else expected in stack I_/N_/C_, but get: " + temp_stack.top() + "\nline: " + std::to_string(numberString));
598
				return false;
599
			}
600

601
		}
602
		else
603
		{
604
			std::string nextCode = fragment.substr(0, fragment.find(" "));
605
			if (nextCode != "R7")
606
			{
607
				if (breachOfExpressionWithNumberConst(token, temp_stack, nextCode) == true )
608
				{
609
					problemDetected("there is problem with expression " + token + " expected operation, but get: before " + temp_stack.top() + "/ after " + nextCode + "\nline: " + std::to_string(numberString));
610
					return false;
611
				}
612
			}
613
			
614
		}
615

616
		
617
		
618
		if (isOpenAnyBracket(token) == true && isCloseAnyBracket(temp_stack.top()) == false)
619
		{
620
			pushStackAndPop(temp_stack, token);
621
			continue;
622
		}
623
		else
624
			if (isOpenAnyBracket(token) == true)
625
			{
626
				problemDetected("Detected )(\nline: " + std::to_string(numberString));
627
				return false;
628
			}
629

630
		if (isCloseAnyBracket(token) == true && temp_stack.top() != "R7")
631
		{
632
			pushStackAndPop(temp_stack, token);
633
			continue;
634
		}
635
		else
636
			if (isCloseAnyBracket(token) == true)
637
			{
638
				problemDetected("Detected ;) in expression: \nline: " + std::to_string(numberString));
639
				return false;
640
			}
641
			
642
		
643
		if (isRepeatWordByCode(&isIdentifierByCode, temp_stack, token) == 0)
644
			return false;
645
		else
646
		{
647
			if (isRepeatWordByCode(&isNumberConstByCode, temp_stack, token) == 0)
648
				return false;
649
			else
650
			{
651
				if (isRepeatWordByCode(&isSymbolConst, temp_stack, token) == 0)
652
					return false;
653
				else
654
				{
655
					if (isRepeatWordByCode(&isOperationByCode, temp_stack, token) == 0)
656
						return false;
657
					else
658
						pushStackAndPop(temp_stack, token);
659
				}
660
			}
661
		}
662
		if (positionTypeConversion(fragment) == 0)
663
		{
664
			pushStackAndPop(temp_stack, fragment.substr(0, 2));
665
			pushStackAndPop(temp_stack, fragment.substr(3, fragment.find("R4") - 2));
666
			pushStackAndPop(temp_stack, fragment.substr(fragment.find("R4"), 2));
667
			fragment.erase(0, 10);
668
			//token = getToken(fragment);
669
		}
670
				
671
	}
672

673
	return true;
674
}
675

676
bool SyntaxAnalisator::breachOfCodition(std::string const& token,std::stack<std::string>const& temp_stack)
677
{
678
	return (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
}
680
bool SyntaxAnalisator::breachOfExpressionWithNumberConst(std::string const& token, std::stack<std::string>const& temp_stack,std::string nextCommand)
681
{
682
	bool isWordConst = (isNumberConstByCode(token) == true || isSymbolConst(token) == true);
683
	if (isWordConst == false)
684
		return false;
685
	if (temp_stack.top() == "R8" || nextCommand == "R8")
686
		return false;
687
	bool operation_word = isOperationByCode(temp_stack.top()) == true;
688
	bool word_operation =  isOperationByCode(nextCommand) == true;
689
	bool bracket_word =  temp_stack.top() == "R3";
690
	bool word_bracket =  nextCommand == "R4";
691
	bool breach = !((operation_word == true && word_operation == true) || (bracket_word == true && word_bracket == true));
692
	return breach == true;
693
}
694

695
int SyntaxAnalisator::isRepeatWordByCode(bool (*pFunctWordByCode)(std::string), std::stack<std::string>& temp_stack, std::string token)
696
{
697
	if ((*pFunctWordByCode)(token) == true && (*pFunctWordByCode)(temp_stack.top()) == true)
698
	{
699
		problemDetected("Detected repeat word! "+token+ "   stack: " + temp_stack.top() + "\nline:"+ std::to_string(numberString));
700
		return false;
701
	}
702
	return 1;
703
}
704

705
bool SyntaxAnalisator::checkReturnExpression(std::string& expr)
706
{
707
	expr.erase(0, 3);
708
	if (parseExpression(expr,false) == false)
709
		return false;
710
	return true;
711
}

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.