একটি সিম্পল ইন্টারমিডিয়েট কোড জেনারেটর তৈরি করা একটি ভালো প্রকল্প যা কম্পাইলার ডিজাইন এবং প্রোগ্রামিং ভাষার গঠন বোঝার জন্য সাহায্য করে। এখানে একটি মৌলিক উদাহরণ দেওয়া হলো যা গাণিতিক এক্সপ্রেশন থেকে ইন্টারমিডিয়েট কোড তৈরি করবে।
ধাপ ১: টোকেনাইজেশন
আমরা আগের উদাহরণে তৈরি করা লেক্সিকাল অ্যানালাইজার ব্যবহার করব, যা ইনপুট গাণিতিক এক্সপ্রেশনকে টোকেনে রূপান্তর করবে।
ধাপ ২: সিনট্যাক্স অ্যানালাইজার
এটি গাণিতিক এক্সপ্রেশন পার্স করতে সাহায্য করবে এবং ইন্টারমিডিয়েট কোড তৈরি করবে।
ধাপ ৩: ইন্টারমিডিয়েট কোড জেনারেটর
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 = []
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}")
# টেস্ট কোড
if __name__ == "__main__":
code = "(2 + 3) * 5 - 10 / 2"
tokens = tokenize(code)
parser = Parser(tokens)
result = parser.parse()
print("Intermediate Code:")
for code in parser.intermediate_code:
print(code)
ধাপ ৪: কোডের ব্যাখ্যা
লেক্সিকাল অ্যানালাইজার: লেক্সিক্যাল অ্যানালাইজারটি কোডকে টোকেনে রূপান্তরিত করে, যা পরে পার্সার দ্বারা ব্যবহার করা হয়।
পার্সার ক্লাস: Parser ক্লাসে গাণিতিক এক্সপ্রেশন পার্স করার জন্য বিভিন্ন ফাংশন রয়েছে:
parse(): প্রধান পার্সিং ফাংশন।expression(),term(),factor(): গাণিতিক অপারেশনগুলিকে পার্স এবং ইন্টারমিডিয়েট কোড তৈরি করে।
ইন্টারমিডিয়েট কোড জেনারেশন: intermediate_code তালিকায় গাণিতিক অপারেশনগুলির জন্য সৃষ্ট কোড সংরক্ষণ করা হয়। টেম্পোরারি ভেরিয়েবল t1, t2, ... ব্যবহার করা হয়।
ফলাফল
এই কোডটি চালানোর পর, আপনি নিম্নলিখিত আউটপুট পাবেন:
Intermediate Code:
t1 = 2 + 3
t2 = t1 * 5
t3 = 10 / 2
t4 = t2 - t3
উপসংহার
এটি একটি সিম্পল ইন্টারমিডিয়েট কোড জেনারেটর তৈরির মৌলিক উদাহরণ। আপনি এই জেনারেটরটিকে আরও উন্নত করতে পারেন, যেমন বিভিন্ন অপারেটর, কাস্টম ফাংশন, এবং এর আউটপুটের গঠন পরিবর্তন করে। এই প্রকল্পটি কম্পাইলার ডিজাইন এবং গাণিতিক এক্সপ্রেশন বোঝার জন্য একটি দুর্দান্ত উপায়।
Read more