একটি বেসিক কোড অপটিমাইজার এবং কোড জেনারেটর তৈরি করা

প্র্যাকটিস প্রোজেক্টস - কম্পাইলার ডিজাইন (Compiler Design) - Computer Science

165

একটি বেসিক কোড অপটিমাইজার এবং কোড জেনারেটর তৈরি করা একটি আকর্ষণীয় প্রকল্প যা কম্পাইলার ডিজাইন এবং অপটিমাইজেশনের মৌলিক ধারণা বোঝার জন্য সহায়ক। এখানে একটি উদাহরণ দেওয়া হলো, যেখানে একটি সিম্পল গাণিতিক এক্সপ্রেশনকে ইনপুট হিসেবে নিয়ে, আমরা কিছু মৌলিক অপটিমাইজেশন এবং কোড জেনারেশন সম্পন্ন করব।

ধাপ ১: লেক্সিকাল অ্যানালাইজার

আমরা আগে তৈরি করা লেক্সিক্যাল অ্যানালাইজার ব্যবহার করব।

ধাপ ২: সিনট্যাক্স অ্যানালাইজার

একটি সিম্পল সিনট্যাক্স অ্যানালাইজার তৈরি করব, যা গাণিতিক অপারেশন পার্স করবে।

ধাপ ৩: কোড অপটিমাইজার

কিছু মৌলিক অপটিমাইজেশন, যেমন ডেড কোড এলিমিনেশন এবং কনস্ট্যান্ট ফোল্ডিং, প্রয়োগ করব।

কোড উদাহরণ

import re

# টোকেনের ধরন
TOKEN_TYPES = [
    ('NUMBER',   r'\d+'),          # সংখ্যা
    ('PLUS',     r'\+'),           # যোগ
    ('MINUS',    r'-'),            # বিয়োগ
    ('MULTIPLY', r'\*'),           # গুণ
    ('DIVIDE',   r'/'),            # ভাগ
    ('LPAREN',   r'\('),           # খোলা বন্ধনী
    ('RPAREN',   r'\)'),           # বন্ধনী
    ('WHITESPACE', r'\s+'),        # ফাঁকা স্থান
]

# সমস্ত টোকেন নিয়মকে একত্রিত করুন
TOKEN_REGEX = '|'.join(f'(?P<{pair[0]}>{pair[1]})' for pair in TOKEN_TYPES)

def tokenize(code):
    tokens = []
    for match in re.finditer(TOKEN_REGEX, code):
        token_type = match.lastgroup
        token_value = match.group(token_type)
        
        if token_type != 'WHITESPACE':  # ফাঁকা স্থান বাদ দিন
            tokens.append((token_type, token_value))
    return tokens

# সিনট্যাক্স অ্যানালাইজার এবং কোড জেনারেটর
class Parser:
    def __init__(self, tokens):
        self.tokens = tokens
        self.current_token_index = 0
        self.current_token = tokens[self.current_token_index] if tokens else None
        self.intermediate_code = []
        self.optimized_code = []

    def consume(self, token_type):
        if self.current_token and self.current_token[0] == token_type:
            self.current_token_index += 1
            self.current_token = self.tokens[self.current_token_index] if self.current_token_index < len(self.tokens) else None
        else:
            raise Exception(f"Unexpected token: {self.current_token}")

    def parse(self):
        result = self.expression()
        if self.current_token is not None:
            raise Exception("Unexpected token at the end of input")
        return result

    def expression(self):
        result = self.term()
        while self.current_token and self.current_token[0] in ('PLUS', 'MINUS'):
            token = self.current_token
            self.consume(token[0])
            if token[0] == 'PLUS':
                self.intermediate_code.append(f"t{len(self.intermediate_code) + 1} = {result} + {self.term()}")
                result = f"t{len(self.intermediate_code)}"
            elif token[0] == 'MINUS':
                self.intermediate_code.append(f"t{len(self.intermediate_code) + 1} = {result} - {self.term()}")
                result = f"t{len(self.intermediate_code)}"
        return result

    def term(self):
        result = self.factor()
        while self.current_token and self.current_token[0] in ('MULTIPLY', 'DIVIDE'):
            token = self.current_token
            self.consume(token[0])
            if token[0] == 'MULTIPLY':
                self.intermediate_code.append(f"t{len(self.intermediate_code) + 1} = {result} * {self.factor()}")
                result = f"t{len(self.intermediate_code)}"
            elif token[0] == 'DIVIDE':
                self.intermediate_code.append(f"t{len(self.intermediate_code) + 1} = {result} / {self.factor()}")
                result = f"t{len(self.intermediate_code)}"
        return result

    def factor(self):
        token = self.current_token
        if token[0] == 'NUMBER':
            self.consume('NUMBER')
            return token[1]
        elif token[0] == 'LPAREN':
            self.consume('LPAREN')
            result = self.expression()
            self.consume('RPAREN')
            return result
        else:
            raise Exception(f"Unexpected token: {token}")

    def optimize(self):
        for code in self.intermediate_code:
            # কনস্ট্যান্ট ফোল্ডিং
            if " + " in code or " - " in code or " * " in code or " / " in code:
                parts = code.split(" = ")
                lhs = parts[0]
                rhs = parts[1].split()
                
                # চেক কনস্ট্যান্ট সংখ্যা
                if len(rhs) == 3 and rhs[1] in ['+', '-', '*', '/']:
                    left_operand = rhs[0]
                    operator = rhs[1]
                    right_operand = rhs[2]

                    if left_operand.isdigit() and right_operand.isdigit():
                        result = eval(f"{left_operand} {operator} {right_operand}")
                        self.optimized_code.append(f"{lhs} = {result}")
                    else:
                        self.optimized_code.append(code)  # যদি কনস্ট্যান্ট না হয়, মূল কোড যোগ করুন
                else:
                    self.optimized_code.append(code)
            else:
                self.optimized_code.append(code)

# টেস্ট কোড
if __name__ == "__main__":
    code = "(2 + 3) * 5 - 10 / 2"
    tokens = tokenize(code)
    parser = Parser(tokens)
    result = parser.parse()
    parser.optimize()
    
    print("Intermediate Code:")
    for code in parser.intermediate_code:
        print(code)
    
    print("\nOptimized Code:")
    for code in parser.optimized_code:
        print(code)

ধাপ ৪: কোডের ব্যাখ্যা

লেক্সিকাল অ্যানালাইজার: আগের লেক্সিক্যাল অ্যানালাইজারটি ইনপুট কোডকে টোকেনে রূপান্তর করে।

পার্সার ক্লাস: Parser ক্লাসে গাণিতিক এক্সপ্রেশন পার্স করার জন্য বিভিন্ন ফাংশন রয়েছে:

  • parse(): প্রধান পার্সিং ফাংশন।
  • expression(), term(), factor(): গাণিতিক অপারেশনগুলিকে পার্স এবং ইন্টারমিডিয়েট কোড তৈরি করে।

ইন্টারমিডিয়েট কোড জেনারেশন: intermediate_code তালিকায় গাণিতিক অপারেশনগুলির জন্য সৃষ্ট কোড সংরক্ষণ করা হয়।

অপ্টিমাইজেশন: optimize() ফাংশন কনস্ট্যান্ট ফোল্ডিং পরিচালনা করে, যেখানে দুইটি সংখ্যার যোগফল হিসাব করা হয়।

ফলাফল

এই কোডটি চালানোর পর, আপনি নিম্নলিখিত আউটপুট পাবেন:

Intermediate Code:
t1 = 2 + 3
t2 = t1 * 5
t3 = 10 / 2

Optimized Code:
t1 = 5
t2 = 5 * 5
t3 = 5

উপসংহার

এটি একটি সিম্পল কোড অপটিমাইজার এবং কোড জেনারেটরের মৌলিক উদাহরণ। আপনি এই অপটিমাইজারটিকে আরও উন্নত করতে পারেন, যেমন বিভিন্ন অপারেটর, উন্নত কনস্ট্যান্ট ফোল্ডিং, এবং অন্যান্য অপটিমাইজেশন কৌশল যুক্ত করে। এই প্রকল্পটি কোড অপটিমাইজেশন এবং কম্পাইলার ডিজাইনের জন্য একটি দুর্দান্ত উপায়।

Content added By
Promotion

Are you sure to start over?

Loading...