संकलन करें


17

इस कार्य में आपको एक प्रोग्राम लिखना होता है जो एक रेगुलर एक्सप्रेशन पढ़ता है और दूसरा प्रोग्राम तैयार करता है जो उस रेगुलर एक्सप्रेशन द्वारा इनपुट स्ट्रिंग को स्वीकार करता है या नहीं। आउटपुट आपके प्रस्तुतिकरण के रूप में उसी भाषा में लिखा गया प्रोग्राम होना चाहिए।

इनपुट

इनपुट एक रेगुलर एक्सप्रेशन है आर निम्नलिखित ABNF (प्रारंभिक उत्पादन नियम है मिलान REGEX):

REGEX       = *( STAR / GROUP / LITERAL / ALTERNATIVE )
STAR        = REGEX '*'
GROUP       = '(' REGEX ')'
LITERAL     = ALPHA / DIGIT
ALTERNATIVE = REGEX '|' REGEX

यदि इनपुट इस व्याकरण से मेल नहीं खाता है, तो आपके प्रोग्राम का व्यवहार अपरिभाषित है।

व्याख्या

एक नियमित अभिव्यक्ति के रूप में इनपुट की व्याख्या करें, जहां *क्लेन-स्टार (मतलब दोहरा हुआ तर्क शून्य या अधिक बार दोहराएं ), |एक विकल्प है, (और )समूह और कोई भी ऑपरेटर नहीं है। समूहन स्टार से अधिक पूर्वता लेता है, तारा संगति पर पूर्वता लेता है, संगति विकल्प से अधिक पूर्वता लेता है।

एक स्ट्रिंग को स्वीकार किया जाता है यदि रेगेक्स पूरे स्ट्रिंग से मेल खाता है।

उत्पादन

कार्यक्रम के उत्पादन है कि एक स्ट्रिंग पढ़ता आपके सबमिशन रूप में एक ही भाषा में लिखे गए एक अन्य कार्यक्रम है रों रनटाइम पर एक कार्यान्वयन परिभाषित रास्ते में, आउटपुट चाहे आर स्वीकार करता रों और उसके बाद समाप्त हो जाता है। आउटपुट उपयोगकर्ता-परिभाषित तरीके से किया जा सकता है, हालांकि स्वीकृत और अस्वीकृत कार्यक्रमों के लिए केवल दो अलग-अलग आउटपुट होने चाहिए।

आप मान सकते हैं कि आपके आउटपुट प्रोग्राम का इनपुट 2 16 -1 बाइट्स से अधिक लंबा नहीं है ।

प्रतिबंध

न तो आपका सबमिशन और न ही आपके सबमिशन से उत्पन्न कोई प्रोग्राम बिलिन फंक्शनलिटी या लाइब्रेरीज़ का इस्तेमाल कर सकता है

  • मैच रेग्जेस
  • नियमित अभिव्यक्ति को बदलना
  • नियमित अभिव्यक्ति संकलित करें
  • एक व्याकरण से पार्सर उत्पन्न करते हैं
  • समस्या को इस तरह से सरल बनाएं कि आपका सबमिशन तुच्छ हो जाए

स्कोरिंग

आपके सबमिशन का स्कोर वर्णों की संख्या है। सबसे कम स्कोर के साथ सबमिशन जीत जाता है।

परीक्षण के मामलों

सभी टेस्टकेस में एक नियमित अभिव्यक्ति, स्वीकृत स्ट्रिंग्स का एक सेट, अस्वीकृत स्ट्रिंग्स का एक सेट और C99 में एक उदाहरण कार्यक्रम होता है जो कि (hyptothetical) C99 सबमिशन का एक मान्य आउटपुट है।

(खाली नियमित अभिव्यक्ति)

स्वीकार किए जाते हैं तार

  1. (खाली इनपुट)

तार हटा दिए

  1. foo
  2. बार
  3. baz
  4. quux

उदाहरण कार्यक्रम

#include <stdio.h>

int main() {
    char input[65536];
    gets(input);

    return input[0] != 0;
}

(b|)(ab)*(a|)( aऔर bबारी - बारी से)

तार स्वीकार किए जाते हैं

  1. a
  2. ba
  3. abababababa
  4. abab

अस्वीकार किए गए तार

  1. afba
  2. foo
  3. babba

उदाहरण कार्यक्रम

#include <stdio.h>

int main() {
  char input[65536];
  int state = 0;

  for (;;) switch (state) {
    case 0: switch (getchar()) {
      case 'a': state = 1; break;
      case 'b': state = 2; break;
      case EOF: return 0;
      default:  return 1;
    } break;
    case 1: switch (getchar()) {
      case 'b': state = 2; break;
      case EOF: return 0;
      default:  return 1;
    } break;
    case 2: switch (getchar()) {
      case 'a': state = 1; break;
      case EOF: return 0;
      default:  return 1;
    } break;
}

(0|1(0|1)*)(|A(0|1)*1) (बाइनरी फ्लोटिंग पॉइंट नंबर)

तार स्वीकार किए जाते हैं

  1. 10110100
  2. 0
  3. 1A00001

अस्वीकार किए गए तार

  1. 011
  2. 10:00 पूर्वाह्न
  3. 1A00
  4. 100A010

1
मुझे लगता है कि इस तरह के कार्यक्रम की return (regex.match(stdin) is not null)अनुमति नहीं है।
beary605

1
आप कहते हैं कि "आउटपुट इनपुट के रूप में उसी भाषा में लिखा गया प्रोग्राम होना चाहिए", लेकिन इनपुट एक regex है। और आपके द्वारा प्रदान किया जाने वाला व्याकरण नियम ग्रुप को शामिल नहीं करता है, जो संभवतः शाब्दिक कोष्ठक को परिभाषित करता है।
पीटर टेलर

@Peter क्षमा करें, मेरा अभिप्राय है कि वे उसी भाषा को प्रस्तुत करने के रूप में लिखें।
फ़ूजएक्सएक्सएल

@ beary605 हाँ, आप सही हैं। अनुभाग प्रतिबंध देखें : न तो आपका सबमिशन और न ही आपके सबमिशन से उत्पन्न कोई प्रोग्राम बिलिन फंक्शनलिटी या लाइब्रेरी का उपयोग कर सकता है जो रेगेक्स (...) से मेल खाते हैं।
FUZxxl

मुझे लगता है कि आपका दूसरा उदाहरण कार्यक्रम गलत है, यह बाहरी स्विच के चारों ओर एक लूप को याद कर रहा है
हस्तुरकुन

जवाबों:


8

रूबी, 641 651 543 वर्ण

H=Hash.new{|h,k|[k]}
d=[[i=0,0,[]]]
o=[?(]
L="t,u,v=d.pop;q,r,s=d.pop;o.pop<?|&&(H[r]<<=t)||(H[q]<<=t;H[r]<<=u);d<<[q,u,s+v]"
gets.chop.chars.map{|c|c==?*&&(q,r,s=d.pop;H[r]|=[q,i+=1];d<<=[r,i,s];next)
eval(L)while/[|)]/=~c ?o[-1]>?(:o[-1]==?.
/[|(]/=~c&&d<<[i+=1,i,o<<c&&[]]||c!=?)&&d<<[i+=1,i+1,["s==#{o<<?.;i}&&c=='#{c}'&&#{i+=1}"]]||o[-1]=?.}
eval(L)while o.size>1
H.map{H.map{|k,v|v.map{|v|H[k]|=H[v]}}}
t,u,v=d[0]
$><<"s=#{H[t]};gets.chop.chars.map{|c|s=s.map{|s|#{v*'||'}}-[!0];#{H.map{|k,v|"s&[#{k}]!=[]&&s|=#{v}"}*?;}};p s&[#{u}]!=[]"

रेगीज़ पार्सर में कई कोने के मामलों के कारण यह रूबी संस्करण काफी लंबा हो गया (शायद मुझे एक अलग दृष्टिकोण की कोशिश करनी चाहिए)। यह एसटीडीआईएन पर नियमित अभिव्यक्ति की अपेक्षा करता है और मिलानकर्ता को एसटीडीयूएसटी के लिए संबंधित रूबी कोड को आउटपुट करता है।

कार्यक्रम सीधे एनएफए- a के लिए कोड उत्पन्न करता है जिसे बाद में मिलान में निष्पादित किया जाता है।

टेस्ट केस 1: (आउटपुट में अतिरिक्त न्यूलाइन और इंडेंटेशन शामिल हैं)

>>>

s=[0];
gets.chop.chars.map{|c|
  s=s.map{|s|}-[!0];
};
p s&[0]!=[]

टेस्ट केस 2:

>>> (b|)(ab)*(a|)

s=[0, 1, 2, 4, 9, 5, 10, 6, 11, 12, 14];
gets.chop.chars.map{|c|
  s=s.map{|s|s==2&&c=='b'&&3||s==6&&c=='a'&&7||s==8&&c=='b'&&9||s==12&&c=='a'&&13}-[!0];
  s&[1]!=[]&&s|=[1, 2, 4, 9, 5, 10, 6, 11, 12, 14];
  s&[3]!=[]&&s|=[3, 4, 9, 5, 10, 6, 11, 12, 14];
  s&[0]!=[]&&s|=[0, 1, 2, 4, 9, 5, 10, 6, 11, 12, 14];
  s&[5]!=[]&&s|=[5, 6];
  s&[7]!=[]&&s|=[7, 8];
  s&[9]!=[]&&s|=[9, 5, 10, 6, 11, 12, 14];
  s&[4]!=[]&&s|=[4, 9, 5, 10, 6, 11, 12, 14];
  s&[11]!=[]&&s|=[11, 12, 14];
  s&[13]!=[]&&s|=[13, 14];
  s&[10]!=[]&&s|=[10, 11, 12, 14]
};
p s&[14]!=[]

एक और उदाहरण:

>>> a|bc

s=[0, 1, 3, 4];
gets.chop.chars.map{|c|
  s=s.map{|s|s==1&&c=='a'&&2||s==4&&c=='b'&&5||s==6&&c=='c'&&7}-[!0];
  s&[0]!=[]&&s|=[0, 1, 3, 4];
  s&[3]!=[]&&s|=[3, 4];
  s&[5]!=[]&&s|=[5, 6];
  s&[2]!=[]&&s|=[2, 7]
};
p s&[7]!=[]

संपादित करें: टिप्पणी में उल्लिखित बग PleaseStand को ठीक करने के लिए एक संक्रमण जोड़ा गया । राज्य के प्रारंभिक परिवर्तन को भी बदल दिया।


011रीगेक्स (0|1(0|1)*)(|A(0|1)*1)परिणामों के लिए इनपुट true- यह होना चाहिए false
कृपया

@PleaseStand फिक्स्ड। कृपया मेरा संपादन देखें।
हॉवर्ड

12

C, 627 अक्षर

यह कार्यक्रम इनपुट के रूप में अपने पहले कमांड-लाइन तर्क को मानता है और अपने उत्पादन के रूप में सी कोड उत्पन्न करता है।

#define A(v) F[v]+strlen(F[v])
#define S sprintf
char*B="&&f%d(s)||f%d(s)",*J="&&f%d(s+%d)",*r,F[256][65536];h=2;e(f,n,o,R,C,O,t,g){for(C=O=f;*r;++r)switch(*r){case 40:r++;e(g=h++,C=h++,0,0);r[1]^42?t=g:(t=C,S(A(t),B,g,C=h++),r++);o=!S(A(O),J,t,o);O=C;break;case 41:goto L;case'|':S(A(C),J,n,o);o=!S(A(O=f),"||1");break;default:r[1]^42?S(A(C),"&&s[%d]==%d",o++,*r,O^f||R++):(o=!S(A(O),J,t=h++,o),O=C=h++,g=h++,S(A(g),"&&*s==%d&&f%d(s+1)",*r++,t),S(A(t),B,g,C));}L:S(A(C),J,n,o);}main(int c,char**v){r=v[1];for(e(1,!S(*F,"&&!*s"),0,0);h--;)printf("f%d(char*s){return 1%s;}",h,F[h]);puts("main(int c,char**v){exit(f1(v[1]));}");}

यहाँ इसके उत्पादन के लिए है (0|1(0|1)*)(|A(0|1)*1)(newlines जोड़ा के साथ):

f11(char*s){return 1&&s[0]==49&&f7(s+1);}
f10(char*s){return 1&&s[0]==48&&f9(s+1)||1&&s[0]==49&&f9(s+1);}
f9(char*s){return 1&&f10(s)||f11(s);}
f8(char*s){return 1&&f7(s+0)||1&&s[0]==65&&f9(s+1);}
f7(char*s){return 1&&f0(s+0);}
f6(char*s){return 1&&f2(s+0);}
f5(char*s){return 1&&s[0]==48&&f4(s+1)||1&&s[0]==49&&f4(s+1);}
f4(char*s){return 1&&f5(s)||f6(s);}
f3(char*s){return 1&&s[0]==48&&f2(s+1)||1&&s[0]==49&&f4(s+1);}
f2(char*s){return 1&&f8(s+0);}
f1(char*s){return 1&&f3(s+0);}
f0(char*s){return 1&&!*s;}
main(int c,char**v){exit(f1(v[1]));}

यदि आप इसके पहले कमांड-लाइन तर्क के रूप में मान्य इनपुट प्रदान करते हैं, तो यह निकास स्थिति 1 लौटाता है। अन्यथा, यह निकास स्थिति 0 देता है।

$ ./regexcompiler '(0 | 1 (0 | 1) *) (! A (0 | 1) * 1)'> floatprog.c
$ gcc -o floatprog floatprog.c
floatprog.c। फ़ंक्शन में 'मुख्य':
floatprog.c: 1: 519: चेतावनी: अंतर्निहित फ़ंक्शन 'बाहर निकलने' की असंगत निहित घोषणा [डिफ़ॉल्ट रूप से सक्षम]
$ ./loloproprog '1A00001' && गूंज अमान्य || गूंज वैध
मान्य
$ ./loloproprog '100A010' && गूंज अमान्य || इको मान्य
अमान्य

या तो प्रोग्राम, यदि आप कमांड-लाइन तर्क प्रदान करने में विफल रहते हैं, तो एक अशक्त सूचक को निष्क्रिय कर देता है, जिससे एक विभाजन दोष होता है। पर्याप्त रूप से लंबा रेगेक्स इस सबमिशन के बफ़र्स को ओवरफ्लो करेगा, और उत्पन्न प्रोग्राम के लिए इनपुट का आकार स्टैक के आकार तक सीमित है। हालांकि, सभी परीक्षण मामले काम करते हैं।

ध्यान दें कि e(g=h++,C=h++,0,0);अपरिभाषित व्यवहार का परिचय। यदि, उदाहरण के लिए, उत्पन्न कार्यक्रम संकलित नहीं करते हैं, तो आप कथन को प्रतिस्थापित करने का प्रयास कर सकते हैं h+=2;e(g=h-1,C=h-2,0,0);, जो पांच वर्णों से अधिक लंबा है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.