ধরা যাক যে আপনি আপনার সমস্ত পদ্ধতি খুঁজে বের করার জন্য আপনার সোর্স কোড পার্স করতে চান, সেগুলি কোথায় সংজ্ঞায়িত করা হয়েছে এবং তারা কী যুক্তি গ্রহণ করে৷
আপনি কিভাবে এটি করতে পারেন?
আপনার প্রথম ধারণা এটির জন্য একটি regexp লিখতে পারে…
কিন্তু একটি ভাল উপায় আছে?
হ্যাঁ!
স্ট্যাটিক বিশ্লেষণ একটি কৌশল যা আপনি যখন সোর্স কোড থেকে তথ্য বের করতে চান তখন ব্যবহার করতে পারেন।
এটি সোর্স কোডকে টোকেনে রূপান্তর করে (পার্সিং) করা হয়।
আসুন সরাসরি এতে প্রবেশ করি!
পার্সার রত্ন ব্যবহার করা
রুবির স্ট্যান্ডার্ড লাইব্রেরিতে একটি পার্সার উপলব্ধ আছে, নাম রিপার। আউটপুট দিয়ে কাজ করা কঠিন তাই আমি চমত্কার পার্সার রত্ন ব্যবহার করতে পছন্দ করি। রুবোকপ তার জাদু করতে এই রত্ন ব্যবহার করে।
এই রত্নটিতে একটি বাইনারিও রয়েছে যা আপনি সরাসরি কিছু কোড পার্স করতে এবং ফলস্বরূপ পার্স ট্রি দেখতে ব্যবহার করতে পারেন৷
এখানে একটি উদাহরণ :
ruby-parse -e '%w(hello world).map { |c| c.upcase }'
আউটপুট এই মত দেখায়:
(block (send (array (str "hello") (str "world")) :map) (args (arg :c)) (send (lvar :c) :upcase))
আপনি রুবি কিভাবে কিছু কোড পার্স করে তা বোঝার চেষ্টা করলে এটি কার্যকর হতে পারে। কিন্তু আপনি যদি নিজের বিশ্লেষণের টুল তৈরি করতে চান তাহলে আপনাকে সোর্স ফাইলটি পড়তে হবে, এটি পার্স করতে হবে এবং তারপর জেনারেট করা ট্রিটি অতিক্রম করতে হবে।
উদাহরণ :
require 'parser/current' code = File.read('app.rb') parsed_code = Parser::CurrentRuby.parse(code)
পার্সার আপনার কোডের একটি AST (অ্যাবস্ট্রাক্ট সিনট্যাক্স ট্রি) ফেরত দেবে। নাম দেখে খুব বেশি ভয় পাবেন না, এটি শোনার চেয়ে সহজ 🙂
AST অতিক্রম করা
এখন আপনি পার্সার ব্যবহার করে আপনার কোড পার্স করেছেন রত্ন আপনাকে ফলস্বরূপ AST অতিক্রম করতে হবে।
আপনি AST::প্রসেসর থেকে উত্তরাধিকারসূত্রে পাওয়া একটি ক্লাস তৈরি করে এটি করতে পারেন .
উদাহরণ :
class Processor < AST::Processor end
তারপর আপনাকে এই ক্লাসটি ইনস্ট্যান্টিয়েট করতে হবে এবং .process এ কল করতে হবে পদ্ধতি:
ast = Processor.new ast.process(parsed_code)
আপনাকে কিছু চালু সংজ্ঞায়িত করতে হবে পদ্ধতি এই পদ্ধতিগুলি AST-তে নোডের নামের সাথে মিলে যায়।
আপনার কোন পদ্ধতিগুলিকে সংজ্ঞায়িত করতে হবে তা আবিষ্কার করতে আপনি হ্যান্ডলার_মিসিং যোগ করতে পারেন আপনার প্রসেসর ক্লাসের পদ্ধতি। এছাড়াও আপনার শুরুতে প্রয়োজন পদ্ধতি।
class Processor < AST::Processor def on_begin(node) node.children.each { |c| process(c) } end def handler_missing(node) puts "missing #{node.type}" end end
এখানেই আমরা আছি :
আপনার রুবি AST এবং একটি মৌলিক প্রসেসর আছে, আপনি যখন এই কোডটি চালাবেন তখন আপনি আপনার AST এর জন্য নোডের ধরন দেখতে পাবেন।
এখন :
আপনাকে সমস্ত চালু বাস্তবায়ন করতে হবে আপনি ব্যবহার করতে চান যে পদ্ধতি. উদাহরণস্বরূপ, যদি আমি সমস্ত উদাহরণ পদ্ধতির নাম তাদের লাইন নম্বর সহ চাই তবে আমি এটি করতে পারি:
def on_def(node) line_num = node.loc.line method_name = node.children[0] puts "Found #{method_name} at line #{line_num}" end
আপনি যখন আপনার প্রোগ্রামটি চালান তখন এটিতে পাওয়া সমস্ত পদ্ধতির নাম প্রিন্ট করা উচিত।
উপসংহার
একটি রুবি স্ট্যাটিক বিশ্লেষণ টুল তৈরি করা যতটা কঠিন মনে হয় ততটা কঠিন নয়। আপনি যদি আরও সম্পূর্ণ উদাহরণ চান তবে আমার ক্লাস_ইনডেক্সার রত্নটি দেখুন। এখন আপনার নিজের টুল তৈরি করার পালা!
অনুগ্রহ করে এই পোস্টটি শেয়ার করুন৷ যদি আপনি এটা উপভোগ করেন! 🙂