कोड के स्निपेट में किस प्रोग्रामिंग भाषा का उपयोग किया जाता है, इसका पता लगाने का सबसे अच्छा तरीका क्या होगा?
कोड के स्निपेट में किस प्रोग्रामिंग भाषा का उपयोग किया जाता है, इसका पता लगाने का सबसे अच्छा तरीका क्या होगा?
जवाबों:
मुझे लगता है कि स्पैम फिल्टर में इस्तेमाल किया जाने वाला तरीका बहुत अच्छा काम करेगा। आप स्निपेट को शब्दों में विभाजित करते हैं। फिर आप ज्ञात स्निपेट्स के साथ इन शब्दों की घटनाओं की तुलना करते हैं, और इस स्निपेट को उस भाषा में लिखा जाता है जिसे आप जिस भाषा में रुचि रखते हैं उसके लिए भाषा X में लिखा गया है।
http://en.wikipedia.org/wiki/Bayesian_spam_filtering
यदि आपके पास बुनियादी तंत्र है तो नई भाषाओं को जोड़ना बहुत आसान है: बस डिटेक्टर को नई भाषा में कुछ स्निपेट के साथ प्रशिक्षित करें (आप इसे एक ओपन सोर्स प्रोजेक्ट फ़ीड कर सकते हैं)। इस तरह यह पता चलता है कि "सिस्टम" सी # स्निपेट में दिखाई देता है और रूबी स्निपेट्स में "पुट" होता है।
मैंने वास्तव में फोरम सॉफ्टवेयर के लिए कोड स्निपेट में भाषा का पता लगाने के लिए इस पद्धति का उपयोग किया है। यह अस्पष्ट मामलों को छोड़कर समय का 100% काम करता है:
print "Hello"
मुझे कोड खोजने दो।
मुझे कोड नहीं मिला इसलिए मैंने एक नया बनाया। यह थोड़ा सरल है, लेकिन यह मेरे परीक्षणों के लिए काम करता है। वर्तमान में यदि आप इसे रूबी कोड की तुलना में बहुत अधिक पायथन कोड खिलाते हैं, तो यह कहने की संभावना है कि यह कोड:
def foo
puts "hi"
end
पायथन कोड है (हालांकि यह वास्तव में रूबी है)। ऐसा इसलिए है क्योंकि पायथन में एक def
कीवर्ड भी है। इसलिए अगर इसे def
अजगर में 1000x और def
रूबी में 100x देखा जाता है तो यह अभी भी अजगर कह सकता है puts
और end
रूबी-विशिष्ट है। आप इसे भाषा के अनुसार देखे गए शब्दों पर नज़र रख सकते हैं और इसे कहीं से विभाजित कर सकते हैं (या इसे प्रत्येक भाषा में समान मात्रा में फीड करके)।
मुझे उम्मीद है इससे आपको मदद मिली होगी:
class Classifier
def initialize
@data = {}
@totals = Hash.new(1)
end
def words(code)
code.split(/[^a-z]/).reject{|w| w.empty?}
end
def train(code,lang)
@totals[lang] += 1
@data[lang] ||= Hash.new(1)
words(code).each {|w| @data[lang][w] += 1 }
end
def classify(code)
ws = words(code)
@data.keys.max_by do |lang|
# We really want to multiply here but I use logs
# to avoid floating point underflow
# (adding logs is equivalent to multiplication)
Math.log(@totals[lang]) +
ws.map{|w| Math.log(@data[lang][w])}.reduce(:+)
end
end
end
# Example usage
c = Classifier.new
# Train from files
c.train(open("code.rb").read, :ruby)
c.train(open("code.py").read, :python)
c.train(open("code.cs").read, :csharp)
# Test it on another file
c.classify(open("code2.py").read) # => :python (hopefully)
$
, इसलिए शायद आपको शब्द सीमा पर विभाजित नहीं होना चाहिए , क्योंकि $
चर के साथ रहना चाहिए। ऑपरेटरों को पसंद करना चाहिए =>
और :=
एक ही टोकन के रूप में एक साथ अटक जाना चाहिए, लेकिन OTH आपको संभवतः एस के आसपास विभाजित करना चाहिए{
क्योंकि वे हमेशा अपने दम पर खड़े होते हैं।
अन्य लोगों द्वारा हल की गई भाषा पहचान:
ओहलो का दृष्टिकोण: https://github.com/blackducksw/ohcount/
जीथब का दृष्टिकोण: https://github.com/github/linguist
आपको यहां कुछ उपयोगी सामग्री मिल सकती है: http://alexgorbatchev.com/wiki/SyntaxHighlighter । एलेक्स ने बड़ी संख्या में विभिन्न भाषाओं को पार्स करने के तरीके का पता लगाने में बहुत समय बिताया है और प्रमुख वाक्यविन्यास तत्व क्या हैं।
गुसेलांग एक संभावित समाधान है:
http://guesslang.readthedocs.io/en/latest/index.html
SourceClassifier भी है:
https://github.com/chrislo/sourceclassifier/tree/master
मुझे इस समस्या में दिलचस्पी एक ब्लॉग लेख में कुछ कोड खोजने के बाद हुई, जिसे मैं पहचान नहीं सका। इस सवाल को जोड़ने के बाद से यह "प्रोग्रामिंग भाषा की पहचान" के लिए पहली खोज हिट थी।
यह बहुत कठिन है और कभी-कभी असंभव है। यह लघु स्निपेट किस भाषा से है?
int i = 5;
int k = 0;
for (int j = 100 ; j > i ; i++) {
j = j + 1000 / i;
k = k + i * j;
}
(संकेत: यह कई में से एक हो सकता है।)
आप विभिन्न भाषाओं का विश्लेषण करने की कोशिश कर सकते हैं और खोजशब्दों के आवृत्ति विश्लेषण का उपयोग करने का निर्णय ले सकते हैं। यदि किसी पाठ में कुछ निश्चित आवृत्तियों के साथ कीवर्ड के कुछ सेट होते हैं, तो यह संभावना है कि भाषा जावा आदि है, लेकिन मुझे नहीं लगता कि आपको कुछ भी मिलेगा जो पूरी तरह से मूर्ख प्रमाण है, जैसा कि आप उदाहरण के लिए सी में एक चर नाम दे सकते हैं। जावा में एक कीवर्ड के रूप में, और आवृत्ति विश्लेषण को मूर्ख बनाया जाएगा।
यदि आप इसे जटिलता में एक पायदान ऊपर ले जाते हैं, तो आप संरचनाओं की तलाश कर सकते हैं, यदि एक निश्चित कीवर्ड हमेशा एक दूसरे के बाद आता है, तो इससे आपको अधिक सुराग मिलेंगे। लेकिन इसे डिजाइन और कार्यान्वित करना भी बहुत कठिन होगा।
हाइलाइट का उपयोग करने के लिए एक विकल्प है। जेएस , जो वाक्य रचना हाइलाइटिंग करता है, लेकिन भाषा की पहचान करने के लिए हाइलाइटिंग प्रक्रिया की सफलता-दर का उपयोग करता है। सिद्धांत रूप में, किसी भी सिंटैक्स हाइलाइटर कोडबेस का उपयोग उसी तरह से किया जा सकता है, लेकिन हाइलाइट.जेएस के बारे में अच्छी बात यह है कि भाषा का पता लगाने को एक विशेषता माना जाता है और इसका उपयोग परीक्षण उद्देश्यों के लिए किया जाता है ।
अद्यतन: मैंने यह कोशिश की और यह अच्छी तरह से काम नहीं किया। संपीड़ित जावास्क्रिप्ट ने इसे पूरी तरह से भ्रमित कर दिया, अर्थात टोकनधारक व्हाट्सएप संवेदनशील है। आम तौर पर, केवल हाइलाइट हिट गिनना बहुत विश्वसनीय नहीं लगता है। एक मजबूत पार्सर, या शायद बेजोड़ अनुभाग मायने रखता है, बेहतर काम कर सकता है।
सबसे पहले, मैं किसी भाषा की विशिष्ट कीवर्क्स को खोजने की कोशिश करूँगा
"package, class, implements "=> JAVA
"<?php " => PHP
"include main fopen strcmp stdout "=>C
"cout"=> C++
etc...
यह इस पर निर्भर करता है कि आपके पास किस प्रकार का स्निपेट है, लेकिन मैं इसे टोकन की एक श्रृंखला के माध्यम से चलाऊंगा और देखूंगा कि यह किस भाषा के बीएनएफ के खिलाफ मान्य है।
अच्छी पहेली।
मुझे लगता है कि सभी भाषाओं का पता लगाना असंभव है। लेकिन आप मुख्य टोकन पर ट्रिगर कर सकते हैं। (कुछ आरक्षित शब्द और अक्सर इस्तेमाल किए जाने वाले वर्ण संयोजन)।
बेन समान सिंटेक्स वाली बहुत सी भाषाएं हैं। तो यह स्निपेट के आकार पर निर्भर करता है।
Prettify एक जावास्क्रिप्ट पैकेज है जो प्रोग्रामिंग भाषाओं का पता लगाने का एक अच्छा काम करता है:
http://code.google.com/p/google-code-prettify/
यह मुख्य रूप से एक वाक्यविन्यास हाइलाइटर है, लेकिन एक स्निपेट से भाषा का पता लगाने के प्रयोजनों के लिए पता लगाने वाले हिस्से को निकालने का एक तरीका है।
मुझे इसकी जरूरत थी इसलिए मैंने अपना खुद का बनाया। https://github.com/bertyhell/CodeClassifier
सही फ़ोल्डर में प्रशिक्षण फ़ाइल जोड़कर यह बहुत आसानी से विस्तार योग्य है। सी # में लिखा है। लेकिन मुझे लगता है कि कोड आसानी से किसी अन्य भाषा में परिवर्तित हो जाता है।
मुझे नहीं लगता कि इसे पूरा करने का एक आसान तरीका होगा। मैं शायद कुछ भाषाओं / भाषाओं की कक्षाओं के लिए अद्वितीय प्रतीकों / सामान्य खोजशब्दों की सूची उत्पन्न करूँगा (जैसे सी-शैली की भाषा के लिए घुंघराले कोष्ठक, बुनियादी भाषाओं के लिए मंद और उप-कीवर्ड, पायथन के लिए डिफॉल्ट कीवर्ड, कार्यात्मक भाषाओं के लिए कीवर्ड) । फिर आप इसे आगे भी कम करने के लिए मूल सिंटैक्स सुविधाओं का उपयोग करने में सक्षम हो सकते हैं।
मुझे लगता है कि भाषाओं के बीच सबसे बड़ा अंतर इसकी संरचना है। इसलिए मेरा विचार सभी भाषाओं में कुछ सामान्य तत्वों को देखना और यह देखना होगा कि वे कैसे भिन्न हैं। उदाहरण के लिए, आप regexes का उपयोग चीजों को लेने के लिए कर सकते हैं जैसे:
और शायद कुछ अन्य चीजें जो अधिकांश भाषाओं के पास होनी चाहिए। फिर एक बिंदु प्रणाली का उपयोग करें। प्रत्येक तत्व के लिए अधिकतम 1 बिंदु पर पुरस्कार यदि रेगेक्स पाया जाता है। जाहिर है, कुछ भाषाएं सटीक एक ही वाक्यविन्यास का उपयोग करेंगी (लूप के लिए अक्सर लिखा जाता है जैसे for(int i=0; i<x; ++i)
कि कई भाषाएं एक ही चीज़ के लिए प्रत्येक अंक प्राप्त कर सकती हैं, लेकिन कम से कम आप इसकी पूरी तरह से अलग भाषा होने की संभावना कम कर रहे हैं)। उनमें से कुछ बोर्ड में 0s स्कोर कर सकते हैं (स्निपेट में एक फ़ंक्शन नहीं होता है, उदाहरण के लिए), लेकिन यह पूरी तरह से ठीक है।
जूल्स के समाधान के साथ इसे मिलाएं, और इसे बहुत अच्छी तरह से काम करना चाहिए। शायद एक अतिरिक्त बिंदु के लिए कीवर्ड की आवृत्तियों की तलाश करें।
दिलचस्प। मेरे पास अलग-अलग स्वरूपों में पाठ को पहचानने का समान कार्य है। YAML, JSON, XML, या जावा गुण? सिंटैक्स त्रुटियों के साथ भी, उदाहरण के लिए, मुझे विश्वास के साथ XML से JSON को अलग बताना चाहिए।
मैं समझती हूं कि हम समस्या को गंभीर कैसे बनाते हैं। जैसा कि मार्क ने कहा, एकल-शब्द टोकन आवश्यक है, लेकिन पर्याप्त नहीं है। हमें बिग्रेड्स या ट्रिगर्स की आवश्यकता होगी। लेकिन मुझे लगता है कि हम यह जानकर वहां से आगे जा सकते हैं कि हम प्रोग्रामिंग भाषाओं को देख रहे हैं। मैंने देखा कि लगभग किसी भी प्रोग्रामिंग भाषा में दो अद्वितीय प्रकार के टोकन हैं - प्रतीक और कीवर्ड । पहचानने के लिए प्रतीक अपेक्षाकृत आसान हैं (कुछ प्रतीक भाषा का हिस्सा नहीं हो सकते हैं)। फिर प्रतीकों के बिग्रेड या ट्रिगर्स, प्रतीकों के चारों ओर अद्वितीय सिंटैक्स संरचनाओं को उठाएंगे। यदि प्रशिक्षण सेट बड़ा है और पर्याप्त पर्याप्त है, तो कीवर्ड एक और आसान लक्ष्य है। एक उपयोगी सुविधा संभावित खोजशब्दों के आसपास बड़ी हो सकती है। एक और दिलचस्प प्रकार का टोकन व्हॉट्सएप है। वास्तव में यदि हम सफेद स्थान द्वारा सामान्य तरीके से टोकन लेते हैं, तो हम इस जानकारी को ढीला कर देंगे। मैं कहूंगा, प्रोग्रामिंग भाषाओं के विश्लेषण के लिए, हम व्हाट्सएप टोकन रखते हैं क्योंकि यह सिंटैक्स संरचना के बारे में उपयोगी जानकारी ले सकता है।
अंत में अगर मैं रैंडम वन की तरह एक क्लासिफायर चुनता हूं, तो मैं गीथब को क्रॉल करूंगा और सभी सार्वजनिक स्रोत कोड इकट्ठा करूंगा। अधिकांश स्रोत कोड फ़ाइल को फ़ाइल प्रत्यय द्वारा लेबल किया जा सकता है। प्रत्येक फ़ाइल के लिए, मैं इसे विभिन्न आकारों के स्निपेट में बेतरतीब ढंग से विभाजित करूँगा। मैं तब विशेषताओं को निकालूंगा और लेबल किए गए स्निपेट का उपयोग करके क्लासिफायरियर को प्रशिक्षित करूंगा। प्रशिक्षण हो जाने के बाद, वर्गीकरण को सटीक और याद रखने के लिए परीक्षण किया जा सकता है।
सबसे अच्छा समाधान जो मुझे आया है , वह है रूबी ऐप पर रूबी में भाषाई मणि का उपयोग करना । यह इसे करने का एक विशिष्ट तरीका है, लेकिन यह काम करता है। यह @nisc द्वारा ऊपर उल्लेख किया गया था, लेकिन मैं आपको इसके उपयोग के लिए अपने सटीक कदम बताऊंगा। (निम्नलिखित कमांड लाइन कमांड में से कुछ ubuntu के लिए विशिष्ट हैं, लेकिन आसानी से अन्य ओएस में अनुवादित किया जाना चाहिए)
यदि आपके पास कोई रेल एप्लिकेशन है जिसे आप अस्थायी रूप से गड़बड़ नहीं करते हैं, तो प्रश्न में अपना कोड स्निपेट सम्मिलित करने के लिए इसमें एक नई फ़ाइल बनाएं। (यदि आपके पास रेल स्थापित नहीं है, तो यहां एक अच्छा मार्गदर्शक है, हालांकि ubuntu के लिए मैं यह सलाह देता हूं । फिर rails new <name-your-app-dir>
उस निर्देशिका में चलाएं और सीडी करें। सब कुछ आपको एक रेल एप्लिकेशन चलाने की आवश्यकता है)।
आपके पास इस का उपयोग करने के लिए एक रेल ऐप है, gem 'github-linguist'
अपने जेमफाइल में जोड़ें (शाब्दिक रूप Gemfile
से आपकी ऐप निर्देशिका में कहा जाता है, कोई अतिरिक्त नहीं)।
फिर माणिक-देव स्थापित करें ( sudo apt-get install ruby-dev
)
तब cmake स्थापित करें ( sudo apt-get install cmake
)
अब आप चला सकते हैं gem install github-linguist
(यदि आपको कोई त्रुटि मिलती है जो आईसीयू आवश्यक कहती है, करें sudo apt-get install libicu-dev
और फिर से प्रयास करें)
(आप एक ऐसा करने के लिए आवश्यकता हो सकती है sudo apt-get update
या sudo apt-get install make
या sudo apt-get install build-essential
अगर ऊपर काम नहीं किया था)
अब सब कुछ सेट हो गया है। अब आप किसी भी समय आप कोड स्निपेट की जांच कर सकते हैं। एक टेक्स्ट एडिटर में, आपने अपना कोड स्निपेट डालने के लिए जो फ़ाइल बनाई है, उसे खोलें (चलिए बस इतना ही कहते हैं app/test.tpl
लेकिन यदि आपके स्निपेट के विस्तार को जानते हैं, तो इसके बजाय इसका उपयोग करें .tpl
। यदि आप एक्सटेंशन नहीं जानते हैं, तो एक का उपयोग न करें। )। अब इस फाइल में अपना कोड स्निपेट पेस्ट करें। कमांड लाइन पर जाएं और चलाएं bundle install
(आपके एप्लिकेशन की निर्देशिका में होना चाहिए)। फिर linguist app/test.tpl
(अधिक सामान्यतः linguist <path-to-code-snippet-file>
) चलाएं । यह आपको टाइप, माइम टाइप और भाषा बताएगा। एकाधिक फ़ाइलों के लिए (या माणिक / रेल एप्लिकेशन के साथ सामान्य उपयोग के लिए) आप bundle exec linguist --breakdown
अपने एप्लिकेशन की निर्देशिका में चला सकते हैं ।
यह बहुत सारे अतिरिक्त काम की तरह लगता है, खासकर यदि आपके पास पहले से ही रेल नहीं है, लेकिन आपको वास्तव में रेल के बारे में कुछ भी जानने की आवश्यकता नहीं है यदि आप इन चरणों का पालन करते हैं और मुझे वास्तव में पता लगाने का एक बेहतर तरीका नहीं मिला है फ़ाइल / कोड स्निपेट की भाषा।
मेरा मानना है कि कोई एकल समाधान नहीं है जो संभवतः यह पहचान सके कि एक स्निपेट किस भाषा में है, बस उस एक स्निपेट पर आधारित है। कीवर्ड ले लो print
। यह किसी भी संख्या में भाषाओं में प्रकट हो सकता है, जिनमें से प्रत्येक अलग-अलग उद्देश्यों के लिए है, और अलग-अलग वाक्यविन्यास हैं।
मुझे कुछ सलाह है मैं वर्तमान में अपनी वेबसाइट के लिए एक छोटा सा कोड कोड लिख रहा हूं जिसका उपयोग प्रोग्रामिंग भाषाओं की पहचान करने के लिए किया जा सकता है। अन्य पोस्टों की तरह, प्रोग्रामिंग भाषाओं की एक बड़ी रेंज हो सकती है, जिसे आपने अभी तक नहीं सुना है, आप उन सभी के लिए जिम्मेदार नहीं हो सकते।
मैंने जो किया है वह यह है कि प्रत्येक भाषा को खोजशब्दों के चयन द्वारा पहचाना जा सकता है। उदाहरण के लिए, पायथन को कई तरीकों से पहचाना जा सकता है। यह संभवत: आसान है यदि आप 'लक्षण' चुनते हैं जो भाषा के लिए निश्चित रूप से अद्वितीय हैं। पायथन के लिए, मैं बयानों का एक सेट शुरू करने के लिए कॉलन का उपयोग करने का गुण चुनता हूं, जो मुझे लगता है कि एक काफी अनूठा गुण है (मुझे गलत होने पर सही करें)।
यदि, मेरे उदाहरण में, आप एक स्टेटमेंट सेट शुरू करने के लिए एक कोलन नहीं पा सकते हैं, तो किसी अन्य संभावित विशेषता पर जाएं, मान लें कि def
फ़ंक्शन को परिभाषित करने के लिए कीवर्ड का उपयोग कर रहे हैं। अब यह कुछ समस्याएं पैदा कर सकता है, क्योंकि रूबी def
एक फ़ंक्शन को परिभाषित करने के लिए कीवर्ड का भी उपयोग करता है । दो (पायथन और रूबी) को अलग बताने के लिए सबसे अच्छा मैच पाने के लिए फ़िल्टरिंग के विभिन्न स्तरों का उपयोग करना है। रूबी end
एक फ़ंक्शन को पूरा करने के लिए कीवर्ड का उपयोग करते हैं , जबकि पायथन के पास एक फ़ंक्शन खत्म करने के लिए कुछ भी नहीं है, बस एक डी-इंडेंट है लेकिन आप वहां नहीं जाना चाहते हैं। लेकिन फिर से, end
लुआ भी हो सकता है , फिर भी मिश्रण में जोड़ने के लिए एक और प्रोग्रामिंग भाषा।
आप देख सकते हैं कि प्रोग्रामिंग भाषाएं बहुत अधिक ओवरले करती हैं। एक कीवर्ड जो एक भाषा में एक कीवर्ड हो सकता है, वह दूसरी भाषा में एक कीवर्ड हो सकता है। उन कीवर्ड के संयोजन का उपयोग करना जो अक्सर एक साथ चलते हैं, जैसे जावा public static void main(String[] args)
उन समस्याओं को खत्म करने में मदद करता है।
जैसा कि मैंने पहले ही कहा है, आपका सबसे अच्छा मौका एक से दूसरे को अलग करने के लिए अपेक्षाकृत अनूठे कीवर्ड या कीवर्ड के सेट की तलाश है। और, अगर आपको यह गलत लगता है, तो कम से कम आपको एक जाना था।
यह साइट भाषाओं की पहचान करने में बहुत अच्छी लगती है, यदि आप एक स्निपेट को वेब रूप में चिपकाने का एक त्वरित तरीका चाहते हैं, बजाय इसे प्रोग्रामिक रूप से करने के: http://dpaste.com/