13-ameliy_paradigma_qq
.pdf
13-ámeliy jumıs. Ishki kompilyatorlardı jaratıw. Kodtı generaciyalaw
Jumıstıń maqseti: Kompilyatorlardıń islew principin hám ishki dúzilisin úyreniw. Kishi kólemdegi ("Oyınshıq") til ushın ápiwayı interpretator yamasa transpiler (bir tilden ekinshi tilge awdarmashı) jaratıw kónlikpesin qáliplestiriw. Leksikalıq analiz (Lexer), Sintaksislik analiz (Parser) hám Kod generaciyası (Code Generation) basqıshların ámeliyatta kórip shıǵıw. Abstract Syntax Tree (AST) túsinigin qollanıw.
Teoriyalıq bólim: Kompilyator – bul joqarı dárejeli tildegi kodtı mashina kodına (yamasa basqa tilge) aylandırıwshı programma.
Process úsh tiykarǵı basqıshtan turadı:
1.Leksikalıq analiz (Tokenizing): Kodtıń tekstin "Tokenlerge" (sózlerge) bóliw. (Mısalı: "int a = 5;" -> [TYPE:int, ID:a, OP:=, NUM:5, SEMI:;]).
2.Sintaksislik analiz (Parsing): Tokenler dizimin logikalıq terekke (AST - Abstract Syntax Tree) aylandırıw. Bul basqısh grammatikalıq qátelerdi tekseredi.
3.Kod generaciyası (Code Gen): AST tereginen maqsetli tildiń (Target Language - Assembly, C++, Bytecode) kodın jaratıw.
ÁMELIY BÓLIM:
Biz C++ tilinde júdá ápiwayı matematikalıq ańlatpalardı (Mısalı: "5 + 3 * 2") esaplaytuǵın yamasa C++ kodına aylandıratuǵın kishi "kompilyator" jazamız.
1-mısal: Leksikalıq Analizator (Lexer)
Másele: Tekstti sanlarǵa hám operatorlarǵa bóliw.
Kod:
#include <iostream>
#include <string>
#include <vector>
#include <cctype>
using namespace std;
// Token túrleri
enum TokenType { NUMBER, PLUS, MINUS, MUL, DIV, END };
struct Token { TokenType type; string value;
};
// Lexer funkciyası
vector<Token> tokenize(string source) { vector<Token> tokens;
for (int i = 0; i < source.length(); i++) { char c = source[i];
if (isdigit(c)) { // San bolsa string num = "";
while (i < source.length() && isdigit(source[i])) { num += source[i++];
}
tokens.push_back({NUMBER, num}); i--; // Cikldi durıslaw
} else if (c == '+') tokens.push_back({PLUS, "+"}); else if (c == '-') tokens.push_back({MINUS, "-"}); else if (c == '*') tokens.push_back({MUL, "*"}); else if (c == '/') tokens.push_back({DIV, "/"});
// Bos orınlardı (whitespace) ótkizip jibere beremiz
}
tokens.push_back({END, ""}); return tokens;
}
int main() {
string code = "12 + 5 * 3"; vector<Token> tokens = tokenize(code);
for (Token t : tokens) {
cout << "Token: " << t.value << " (" << t.type << ")" << endl;
}
return 0;
}
2-mısal: Ápiwayı Parser hám Interpretator
Másele: Tokenlerdi oqıp, nátiyjeni birden esaplaw (Tek + hám - ushın).
Kod:
// ... (Lexer kodı saqlanadı) ...
class Interpreter { vector<Token> tokens; int pos = 0;
public:
Interpreter(vector<Token> t) : tokens(t) {}
// Aǵımdaǵı tokendi kóriw
Token peek() { return tokens[pos]; }
// Tokendi "jep qoyıw" hám alǵa jılıw
Token consume() { return tokens[pos++]; }
// Sanlardı oqıw
int parseNumber() { Token t = consume(); return stoi(t.value);
}
// Baslı esaplaw funkciyası int parseExpression() {
int left = parseNumber(); // Birinshi sandı alamız
while (peek().type == PLUS || peek().type == MINUS) { Token op = consume();
int right = parseNumber(); // Ekinshi sandı alamız
if (op.type == PLUS) left += right; else left -= right;
}
return left;
}
};
int main() {
string code = "10 + 5 - 3"; vector<Token> tokens = tokenize(code);
Interpreter interpreter(tokens);
cout << "Nátiyje: " << interpreter.parseExpression() << endl; // 12 return 0;
}
3-mısal: Kod Generaciyası (Transpiler)
Másele: Biziń "oyınshıq" tilimizdegi ańlatpanı C++ kodına aylandırıw.
Kirisiw: "PRINT 5 + 2"
Shıǵıw: "std::cout << 5 + 2 << std::endl;"
Kod:
#include <iostream> #include <string> #include <vector> using namespace std;
// Ápiwayı generator
string generateCpp(string input) {
string output = "#include <iostream>\nint main() {\n";
if (input.rfind("PRINT ", 0) == 0) { // Eger PRINT penen baslansa string expr = input.substr(6); // "PRINT " sózin alıp taslaymız output += " std::cout << " + expr + " << std::endl;\n";
}
output += " return 0;\n}"; return output;
}
int main() {
string myCode = "PRINT 10 * 10"; string cppCode = generateCpp(myCode);
cout << "--- Generaciyalanǵan C++ Kod ---" << endl; cout << cppCode << endl;
return 0;
}
4-mısal: AST (Abstract Syntax Tree) jaratıw (Koepttegi koncepciya)
Sintaksislik terek – bul kodtıń ierarxiyalıq kórinisi.
Mısalı: "5 + 3 * 2"
Terek:
(+)
/ \ |
|
(5) |
(*) |
/ |
\ |
(3) |
(2) |
Parser usı terekti qurıwı kerek.
Kod (Struktura): struct Node {
string value;
Node* left = nullptr;
Node* right = nullptr;
};
//... Parser terekti quradı hám keyin onı aylanıp shıǵıp (traverse) kod generaciya etedi.
//Bul tolıq kompilyator ushın quramalı process.
ÁMELIY TAPSÍRMALAR
1-tapsırma: Keńeytilgen Lexer.
1-mısaldaǵı Lexerdi keńeytiń. Ol qawsırmalardı '(' , ')' hám teńlik belgisin '=' tanıytuǵın bolsın.
Kirisiw: "(10 + 2) = 12" -> Tokenlerdi shıǵarıń.
2-tapsırma: Kóbeytiw hám Bóliwdi qollaw.
2-mısaldaǵı Interpretatordı ózgertiń. Ol * hám / ámellerin qollasın.
Dıqqat: Kóbeytiw/Bóliw ámelleri Qosıw/Alıwdan joqarı prioritetke iye bolıwı kerek. (Bunıń ushın parseTerm() hám parseFactor() funkciyaların bólek jazıw kerek).
3-tapsırma: Kod generator (Variables).
3-mısaldaǵı generatorǵa ózgeriwshi járiyalawdı qosıń.
Kirisiw: "VAR x = 100"
Shıǵıw: "int x = 100;"
(String operaciyaları arqalı isleń).
4-tapsırma: Pútin emes sanlar (Double support).
Lexer hám Interpretatordı sonday etip ózgertiń, ol 3.14 sıyaqlı bólshek sanlardı da (double) qayta isley alsın. (Noqat belgisin san quramında dep esaplań).
5-tapsırma: JIT (Just-In-Time) koncepciyası (Simulyaciya).
Kishi programma jazıń. Ol paydalanıwshıdan arifmetikalıq string (mısalı "5+5") qabıllasın.
1.Onı C++ faylına (temp.cpp) jazsın.
2.System("g++ temp.cpp -o temp.exe") arqalı kompilyaciya qılsın.
3.System("./temp.exe") arqalı orınlap, nátiyjeni kórsetsin.
(Bul eń ápiwayı JIT/Transpiler modeli).
