सी चर घोषणा को पढ़ें


42

पृष्ठभूमि

C में परिवर्तनीय घोषणा विवरण में तीन भाग होते हैं: चर का नाम , इसका आधार प्रकार और प्रकार संशोधक

तीन प्रकार के संशोधक हैं:

  • सूचक *(उपसर्ग)
  • सरणी [N](पोस्टफ़िक्स)
  • फ़ंक्शन ()(पोस्टफ़िक्स)
    • आप पार्न्स के अंदर फ़ंक्शन तर्कों की एक सूची निर्दिष्ट कर सकते हैं, लेकिन इस चुनौती के लिए, आइए इसे अनदेखा करें और बस उपयोग करें ()(जिसका तकनीकी अर्थ है "फ़ंक्शन किसी भी तरह के तर्क ले सकता है")।

और नोटेशन पढ़ने का एक तरीका इस प्रकार है:

int i;             // i is an int
float *f;          // f is a pointer to a float
my_struct_t s[10]; // s is an array of 10 my_struct_t
int func();        // func is a function returning an int

पकड़ यह है कि हम इन सभी को मिला सकते हैं ताकि अधिक जटिल प्रकार का निर्माण किया जा सके, जैसे कि सरणी का सरणी या फ़ंक्शन पॉइंटर्स का पॉइंटर या पॉइंटर्स से व्यूअर का सरणी :

int arr[3][4];
// arr is an array of 3 arrays of 4 ints

int (*fptrs[10])();
// fptrs is an array of 10 pointers to functions returning an int

float *(*p)[16];
// p is a pointer to an array of 16 pointers to float

मैंने इन जटिल कथनों को कैसे पढ़ा?

  1. चर नाम से प्रारंभ करें। (name) is ...
  2. उच्चतम वरीयता वाले संशोधक का चयन करें।
  3. इसे पढ़ें:
    • * -> pointer to ...
    • [N] -> array of N ...
    • () -> function returning ...
  4. 2 और 3 को दोहराएं जब तक संशोधक समाप्त नहीं हो जाते।
  5. अंत में, आधार प्रकार पढ़ें। ... (base type).

C में, उपसर्ग ऑपरेटर उपसर्ग ऑपरेटरों पर पूर्वता लेते हैं, और प्रकार संशोधक कोई अपवाद नहीं हैं। इसलिए, []और ()पहले बांधें, फिर *। Parens की एक जोड़ी के अंदर कुछ भी (...)(फ़ंक्शन ऑपरेटर के साथ भ्रमित नहीं होना) पहले कुछ भी बाहर से बांधता है।

सचित्र उदाहरण:

int (*fptrs[10])();
      fptrs           fptrs is ...
           [10]       array of 10 ... // [] takes precedence over *
    (*         )      pointer to ...
                ()    function returning ...
int                   int

कार्य

सी में लिखे गए वेरिएबल डिक्लेरेशन स्टेटमेंट की एक लाइन को देखते हुए, ऊपर बताए गए तरीके का उपयोग करके, लाइन का वर्णन करने वाले अंग्रेजी एक्सप्रेशन को आउटपुट करें।

इनपुट

इनपुट एकल सी स्टेटमेंट है जिसमें एकल आधार प्रकार, एकल चर नाम, शून्य या अधिक प्रकार के संशोधक और अंतिम अर्धविराम शामिल हैं। आपको ऊपर दिए गए सभी सिंटैक्स तत्वों को लागू करना होगा, साथ ही:

  • आधार प्रकार और चर नाम दोनों नियमित अभिव्यक्ति से मेल खाते हैं [A-Za-z_][A-Za-z0-9_]*
  • सैद्धांतिक रूप से, आपके कार्यक्रम को असीमित संख्या में संशोधक का समर्थन करना चाहिए।

आप निम्नलिखित तरीकों से अन्य सी सिंटैक्स तत्वों को सरल कर सकते हैं (पूर्ण कार्यान्वयन भी स्वागत है):

  • आधार प्रकार हमेशा एक शब्द है, जैसे int, float, uint32_t, myStruct। जैसे कुछ unsigned long longपरीक्षण नहीं किया जाएगा।
  • सरणी संकेतन के लिए [N], संख्या Nहमेशा आधार 10 में लिखा गया एक एकल धनात्मक पूर्णांक होगा । चीजों की तरह int a[5+5], int a[SIZE]या int a[0x0f]परीक्षण नहीं किया जाएगा।
  • फ़ंक्शन संकेतन के लिए (), कोई भी पैरामीटर निर्दिष्ट नहीं किया जाएगा, जैसा कि ऊपर बताया गया है।
  • व्हाट्सएप के लिए, केवल स्पेस कैरेक्टर 0x20का उपयोग किया जाएगा। आप अपने कार्यक्रम को व्हॉट्सएप के विशिष्ट उपयोग के लिए प्रतिबंधित कर सकते हैं, जैसे
    • आधार प्रकार के बाद केवल एक स्थान का उपयोग करें
    • टोकन के बीच हर जगह एक जगह का उपयोग करें
  • हालाँकि, आप एक टोकन विभाजक होने की तुलना में अधिक जानकारी देने के लिए दो या अधिक लगातार रिक्त स्थान का उपयोग नहीं कर सकते हैं।

सी सिंटैक्स के अनुसार, निम्नलिखित तीन संयोजन अमान्य हैं, और इस प्रकार इसका परीक्षण नहीं किया जाएगा:

  • f()() समारोह वापसी समारोह
  • f()[] समारोह रिटर्निंग सरणी
  • a[]() एन कार्यों का सरणी

सी डेवलपर्स इसके बजाय इन समकक्ष रूपों का उपयोग करते हैं (और ये सभी परीक्षण मामलों में शामिल हैं):

  • (*f())()कार्य करने के लिए रिटर्निंग पॉइंटर
  • *f()सरणी के पहले तत्व के लिए रिटर्निंग पॉइंटर
  • (*a[])()कार्य करने के लिए एन संकेत की सरणी

उत्पादन

आउटपुट एक अंग्रेजी वाक्य है। आपको अंग्रेजी व्याकरण का सम्मान करने की आवश्यकता नहीं है (लेकिन यदि आप चाहें तो) अंग्रेजी, जैसे a, an, the, एकवचन / बहुवचन रूपों और अंतिम बिंदु (अवधि) का उपयोग कर सकते हैं। प्रत्येक शब्द को एक या अधिक व्हाट्सएप (स्पेस, टैब, न्यूलाइन) द्वारा अलग किया जाना चाहिए ताकि परिणाम मानव-पठनीय हो।

फिर, यहाँ रूपांतरण प्रक्रिया है:

  1. चर नाम से प्रारंभ करें। (name) is ...
  2. उच्चतम वरीयता वाले संशोधक का चयन करें।
  3. इसे पढ़ें:
    • * -> pointer to ...
    • [N] -> array of N ...
    • () -> function returning ...
  4. 2 और 3 को दोहराएं जब तक संशोधक समाप्त नहीं हो जाते।
  5. अंत में, आधार प्रकार पढ़ें। ... (base type).

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

int i;              // i is int
float *f;           // f is pointer to float
my_struct_t s[10];  // s is array of 10 my_struct_t
int func();         // func is function returning int
int arr[3][4];      // arr is array of 3 array of 4 int
int (*fptrs[10])(); // fptrs is array of 10 pointer to function returning int
float *(*p)[16];    // p is pointer to array of 16 pointer to float

_RANdom_TYPE_123 (**(*_WTH_is_TH15)())[1234][567];
/* _WTH_is_TH15 is pointer to function returning pointer to pointer to array of
   1234 array of 567 _RANdom_TYPE_123 */

uint32_t **(*(**(*(***p)[2])())[123])[4][5];
/* p is pointer to pointer to pointer to array of 2 pointer to function returning
   pointer to pointer to array of 123 pointer to array of 4 array of 5 pointer to
   pointer to uint32_t */

uint32_t (**((*(**(((*(((**(*p)))[2]))())))[123])[4])[5]);
// Same as above, just more redundant parens

some_type (*(*(*(*(*curried_func())())())())())();
/* curried_func is function returning pointer to function returning pointer to
   function returning pointer to function returning pointer to
   function returning pointer to function returning some_type */

स्कोरिंग और जीत मानदंड

यह एक चुनौती है। सबसे कम संख्या के बाइट्स वाला कार्यक्रम जीतता है।


9
संबंधित: cdecl.org
user202729

int arr[3][4];है an array of 3 arrays of 4 ints(जैसा कि आप कहते हैं), या an array of 4 arrays of 3 ints?
चार्ली

1
@ चार्ली पूर्व सही है। sizeof(arr[0]) == sizeof(int[4]), इसलिए एक आइटम arrमें चार intएस होते हैं।
बुबलर

1
क्या इनपुट ;लाइन के अंत में होता है?
ब्लैक उल्लू काई

2
@KamilDrakari यह बाद की बात है। "पॉइंटर टू फंक्शन" आवश्यक रूप से "पॉइंटर ऑफ़ व्यूअर" है, जो सी में पूरी तरह से मान्य है
बब्लर

जवाबों:


17

पायथन 3 , 331 312 294 261 240 बाइट्स

from re import*
class V(str):__pos__=lambda s:V(s+'pointer to ');__call__=lambda s:V(s+'function returning ');__getitem__=lambda s,i:V(s+'array of %i '%i)
t,e=input().split()
print(eval(sub('\*','+',sub('(\w+)',r'V("\1 is ")',e[:-1],1)))+t)

इसे ऑनलाइन आज़माएं!

-19 बाइट्स को अजगर 2 पर स्विच करके और क्लास की परिभाषा को एक में डालकर exec

से regex बदलकर -18 बाइट्स [a-zA-Z_][a-zA-Z0-9_]*करने के लिए \\w+, केविन Cruijssen करने के लिए धन्यवाद

-33 बाइट्स कुछ क्लास डेफिनेशन मैजिक काम करके और str का उपयोग करके, लिन के लिए धन्यवाद, अजगर 3 में वापस बदल रहा है

-21 बाइट्स को एक साथ कई रेगीज मर्ज करके, infmagic2047 को धन्यवाद

आवश्यकता है कि इनपुट (प्रकार और अभिव्यक्ति के बीच) में केवल एक स्थान निहित है।

मुझे लगता है कि यह समस्या का एक बहुत ही अनूठा तरीका है। यह ज्यादातर इस तथ्य का उपयोग करता है कि पायथन स्वयं जैसे तार का मूल्यांकन कर सकता है (**((*(**(((*(((**(*p)))[2]))())))[123])[4])[5])और फ़ंक्शन कॉल, सरणी इंडेक्स और पॉइंटर्स का सही अनुक्रम प्राप्त करता है - और उपयोगकर्ता इन पर अधिभार लगा सकता है।


1
अच्छा दृष्टिकोण, मुझ से +1! आप कुछ बाइट्स को बचाने के [a-zA-Z_][A-Za-z0-9_]*लिए गोल्फ कर सकते हैं [a-zA-Z_]\\w*। संपादित करें: वास्तव में, मुझे लगता है कि आप \\w+इसके बजाय बस का उपयोग कर सकते हैं [a-zA-Z_][A-Za-z0-9_]*
केविन क्रूज़सेन

मुझे यह दृष्टिकोण पसंद है :) यहां यह 253 बाइट्स में है
लिन

1
ये एक अच्छा बिंदु है। 261 तो यह है।
लिन

1
आप पाइथन 3.6 के [0]बजाय का उपयोग कर सकते हैं .group()
infmagic2047


13

रेटिना 0.8.2 , 142 138 128 117 बाइट्स

(\w+) (.+);
($2) $1
\(\)
 function returning
\[(\d+)?]
 array of$#1$* $1
+`\((\**)(.+)\)
$2$1
\*
 pointer to
1` 
 is 

इसे ऑनलाइन आज़माएं! लिंक में परीक्षण के मामले शामिल हैं। बेहतर व्याकरण । संपादित करें: @ DLosc के पिप समाधान को पोर्ट करके 10 21 बाइट्स सहेजे गए। स्पष्टीकरण:

(\w+) (.+);
($2) $1

प्रकार को अंत तक ले जाएं और शेष घोषणा को ()उस स्थिति में लपेटें, जब उसमें बाहरी हो *

\(\)
 function returning

किसी भी कार्य को संसाधित करें।

\[(\d+)?]
 array of$#1$* $1

किसी भी सरण की प्रक्रिया करें।

+`\((\**)(.+)\)
$2$1

किसी भी संकेत को उनके कोष्ठक के अंत में ले जाएं, और कोष्ठक को हटा दें, बार-बार बाहरी कोष्ठक से अंदर की ओर से काम करते हुए।

\*
 pointer to

किसी भी संकेत प्रक्रिया।

1` 
 is 

डालें is


7

जावा 11, 469 467 463 450 बाइट्स

s->{String r="",t,S[];for(s=s.replace("()","~");s.contains("(");s=s.replace(t,"").replace("()",""),r+=t+";")t=s.replaceAll(".*(\\([^()]+\\)).*","$1");S=s.split(" ");t=S[0];r+=r.isEmpty()?S[1]:s;S=r.split(";");r=S[0].replaceAll(".*?(\\w+).*","$1 is ");for(var p:S)r+=p.replaceAll("[A-Za-z_]+\\d+|[^\\[\\d]","").replaceAll("\\[(\\d+)","array of $1 ")+(p.contains("~")?"function returning ":"")+"pointer to ".repeat(p.split("\\*").length-1);return r+t;}

इसे ऑनलाइन आज़माएं।

स्पष्टीकरण:

s->{               // Method with String as both parameter and return-type
  String r="",     //  Result-String, starting empty
         t,        //  Temp-String, starting uninitialized
         S[];      //  Temp String-array, starting uninitialized
  for(s=s.replace("()","~");
                   //  Replace all "()" in the input `s` with "~"
      s.contains("(");
                   //  Loop as long as the input `s` still contains "("
      ;            //    After every iteration:
       s=s.replace(t,"")
                   //     Remove `t` from `s`
          .replace("()",""),
                   //     And also remove any redundant parenthesis groups
       r+=t+";")   //     Append `t` and a semi-colon to the result-String
    t=s.replaceAll(".*(\\([^()]+\\)).*","$1");
                   //   Set `t` to the inner-most group within parenthesis
  S=s.split(" ");  //  After the loop, split the remainder of `s` on the space
  t=S[0];          //  Set `t` to the first item (the type)
  r+=              //  Append the result-String with:
    r.isEmpty()?   //   If the result-String is empty
                   //   (so there were no parenthesis groups)
     S[1]          //    Set the result-String to the second item
    :              //   Else:
     s;            //    Simple append the remainder of `s`
  S=r.split(";");  //  Then split `r` on semi-colons
  r=S[0].replaceAll(".*?(\\w+).*",
                   //  Extract the variable name from the first item
     "$1 is ");    //  And set `r` to this name appended with " is "
  for(var p:S)     //  Loop over the parts split by semi-colons:
    r+=            //   Append the result-String with:
      p.replaceAll("[A-Za-z_]+\\d+
                   //    First remove the variable name (may contain digits)
         |[^\\[\\d]","")
                   //    And then keep only digits and "["
       .replaceAll("\\[(\\d+)",
                   //    Extract the number after "["
         "array of $1 ")
                   //    And append the result-String with "array of " and this nr
      +(p.contains("~")?
                   //    If the part contains "~"
         "function returning "
                   //     Append the result-String with "function returning "
       :           //    Else:
        "")        //     Leave the result-String the same
      +"pointer to ".repeat(
                   //    And append "pointer to " repeated
         p.split("\\*").length-1);
                   //    the amount of "*" in the part amount of time
  return r         //  Then return the result-String
          +t;}     //  appended with the temp-String (type)

निरर्थक कोष्ठकों के साथ परीक्षण के मामले में विफल रहता है।
बबलर

@ बब्बलर आह, उस नए टेस्ट केस पर ध्यान नहीं दिया। सौभाग्य से यह एक आसान तय है।
केविन क्रूज़सेन

6

बैश + सीडीसीएल + जीएनयू सेड, 180

cdeclएक आदरणीय यूनिक्स उपयोगिता है जो कि यहां सबसे अधिक आवश्यक है, लेकिन I / O आवश्यकताओं से मेल खाने के लिए, कुछ sedपूर्व और बाद के प्रसंस्करण की आवश्यकता होती है:

sed -r 's/^/explain struct /;s/struct (int|char double|float|void) /\1 /;s/\bfunc/_func/g'|cdecl|sed -r 's/^declare //;s/as/is/;s/struct //g;s/([0-9]+) of/of \1/g;s/\b_func/func/g'
  • व्याकरण को सही करने का कोई प्रयास नहीं किया गया।

पूर्व-प्रसंस्करण:

  • s/^/explain struct /- प्रत्येक पंक्ति के प्रारंभ में "संरचना की व्याख्या करें" जोड़ें
  • s/struct (int|char double|float|void) /\1 /- structC भाषा प्रकारों के साथ काम करते समय निकालें
  • s/\bfunc/_func/g - "func" को cdecl द्वारा एक कीवर्ड के रूप में पहचाना जाता है - इसे दबाएं

सीड पोस्ट-प्रोसेसिंग:

  • s/^declare // - लाइन की शुरुआत में "घोषणा" को हटा दें
  • s/as/is/ - आत्म-व्याख्यात्मक
  • s/struct //g - सभी "संरचना" कीवर्ड निकालें
  • s/([0-9]+) of/of \1/g - "का सही क्रम"
  • s/\b_func/func/g - पूर्व प्रसंस्करण में प्रतिस्थापित किसी भी "_func" को वापस लाएं

कार्रवाई में:

$ < cdecls.txt sed -r 's/^/explain struct /;s/struct (int|char double|float|void) /\1 /;s/\bfunc/_func/g'|cdecl|sed -r 's/^declare //;s/as/is/;s/struct //g;s/([0-9]+) of/of \1/g;s/\b_func/func/g'
i is int
f is pointer to float
s is array of 10 my_struct_t
func is function returning int
arr is array of 3 array of 4 int
fptrs is array of 10 pointer to function returning int
p is pointer to array of 16 pointer to float
_WTH_is_TH15 is pointer to function returning pointer to pointer to array of 1234 array of 567 _RANdom_TYPE_123
p is pointer to pointer to pointer to array of 2 pointer to function returning pointer to pointer to array of 123 pointer to array of 4 array of 5 pointer to pointer to uint32_t
p is pointer to pointer to pointer to array of 2 pointer to function returning pointer to pointer to array of 123 pointer to array of 4 array of 5 pointer to pointer to uint32_t
curried_func is function returning pointer to function returning pointer to function returning pointer to function returning pointer to function returning pointer to function returning some_type
$ 

क्या यह s/\bfu/_fu/gपूर्ण funcप्रतिस्थापन के बाइट्स को करने और बचाने के लिए पर्याप्त होगा ?
DLosc

रुको यह एक वास्तविक उपयोगिता है? मैंने हमेशा सोचा है कि यह वेबसाइट का नाम है
phuclv

@phuclv cdecl एक वास्तविक उपयोगिता है, और सी घोषणाओं की जाँच के लिए वास्तव में उपयोगी है।
पेट्रीसिया शहनहान


नाम के एक चर के लिए विफल as(रिक्त स्थान के लिए +4 बाइट्स)। मेरे पास पहुंच नहीं है, cdeclलेकिन मुझे लगता है कि आप 64 बाइट्स का उपयोग करके बचा सकते हैं sed -r 's/^(\w+)(\W+)/explain struct \1_\2_/'|cdecl|sed -r 's/^declare struct _|_$//;s/ as / is /;s/([0-9]+) of/of \1/g'
नील

6

पिप -s , 152 150 148 139 137 126 125 123 बाइट्स

तीसरा तरीका!

YaRs" ("R';')R`\[(\d+)]`` array of \1`R"()"" function returning"L#aYyR`\((\**)(.+)\)`{c." pointer to"X#b}{[b"is"g@>2a]}Vy^s

कमांड-लाइन इनपुट के रूप में घोषणा लेता है। इसे ऑनलाइन आज़माएं!

व्याख्या

कोड तीन भागों में है: कार्यों और सरणियों का प्रारंभिक सेटअप और हैंडलिंग; एक लूप जो कोष्ठकों और बिंदुओं को संभालता है; और एक अंतिम पुनर्व्यवस्था।

सेटअप, फ़ंक्शंस और सरणियाँ

हम पूरे घोषणा parenthesized किया जाना है, (इस लूप पर बाद में साथ में मदद करता है) तो हम बदल चाहते type ...;में type (...)। फिर, निरीक्षण करें कि फ़ंक्शंस और सरणियों के विवरण के साथ कोई पुन: निर्धारण नहीं किया जाता है, इसलिए हम अंतिम आउटपुट को प्रभावित किए बिना उन सभी प्रतिस्थापनों को पहले कर सकते हैं।

Y                         Yank into y variable...
 a                        The result of a (the cmdline arg)...
  R s                     Replace the space
   " ("                    with " ("
  R ';                    Replace the semicolon
   ')                      with a closing paren
  R `\[(\d+)]`            Replace digits in square brackets
   ` array of \1`          with " array of <digits>"
  R "()"                  Replace function parens
   " function returning"   with " function returning"

यदि हमारा मूल इनपुट था float *((*p()))[16];, तो अब हमारे पास है float (*((*p function returning)) array of 16)

कोष्ठक और संकेत

हम कोष्ठक की सबसे बाहरी जोड़ी और किसी भी तार की जगह पर एक लूप चलाते हैं, जो तुरंत खोलने वाले पेरेन के अंदर होता है।

L#a                   Loop len(a) times (enough to complete all replacements):
 Y                    Yank into y variable...
  y                   The result of y...
   R `\((\**)(.+)\)`  Replace open paren, 0 or more asterisks (group 1), 1 or more
                      characters (group 2), and close paren
    {                  with this callback function (b = group 1, c = group 2):
     c .               The stuff in the middle, concatenated to...
      " pointer to"    that string
       X #b            repeated len(asterisks) times
    }

उदाहरण के चरण:

float (*((*p function returning)) array of 16)
float ((*p function returning)) array of 16 pointer to
float (*p function returning) array of 16 pointer to
float p function returning pointer to array of 16 pointer to

साफ - सफाई

केवल एक चीज शेष है जो प्रकार को अंत तक ले जाती है और "" है:

{[b"is"g@>2a]}Vy^s
               y^s  Split y on spaces
{            }V     Use the resulting list as arguments to this function:
 [          ]        Return a list of:
  b                   2nd argument (the variable name)
   "is"               That string
       g@>2           All arguments after the 2nd
           a          1st argument (the type)
                    The resulting list is printed, joining on spaces (-s flag)

जैसी परिभाषाओं के लिए int x;, इस दृष्टिकोण के परिणामस्वरूप एक अतिरिक्त स्थान होगा, जिसे चुनौती की अनुमति है।


5

जावास्क्रिप्ट (ईएस 6), 316 ... 268 253 बाइट्स

s=>(g=s=>[/\d+(?=])/,/\*/,/!/,/.+ /,/\w+/].some((r,i)=>(S=s.replace(r,s=>(O=[O+`array of ${s} `,O+'pointer to ','function returning '+O,O+s,s+' is '+O][i],'')))!=s)?g(S):'',F=s=>(O='',S=s.replace(/\(([^()]*)\)/,g))!=s?O+F(S):g(s)+O)(s.split`()`.join`!`)

इसे ऑनलाइन आज़माएं!

टिप्पणी की गई

हेल्पर फ़ंक्शन

g = s =>                             // s = expression to parse
  [                                  // look for the following patterns in s:
    /\d+(?=])/,                      //   array
    /\*/,                            //   pointer
    /!/,                             //   function
    /.+ /,                           //   type
    /\w+/                            //   variable name
  ].some((r, i) =>                   // for each pattern r at index i:
    ( S = s.replace(                 //   S = new string obtained by removing
      r,                             //       the pattern matching r from s
      s => (                         //     using the first match s and the index i,
        O = [                        //     update the output O:
          O + `array of ${s} `,      //       array
          O + 'pointer to ',         //       pointer
          'function returning ' + O, //       function
          O + s,                     //       type
          s + ' is ' + O             //       variable name
        ][i],                        //
        ''                           //     replace the match with an empty string
    )))                              //   end of replace()
    != s                             //   make some() succeed if S is not equal to s
  ) ?                                // end of some(); if truthy:
    g(S)                             //   do a recursive call with S
  :                                  // else:
    ''                               //   stop recursion and return an empty string

मुख्य हिस्सा

s => (                 // s = input
  g = …,               // define the helper function g (see above)
  F = s => (           // F = recursive function, taking a string s
    O = '',            //   O = iteration output, initialized to an empty string
    S = s.replace(     //   S = new string obtained by removing the next expression from s
      /\(([^()]*)\)/,  //     look for the deepest expression within parentheses
      g                //     and process it with the helper function g
    )                  //   end of replace()
  ) != s ?             // if S is not equal to s:
    O + F(S)           //   append O to the final output and do a recursive call with S
  :                    // else (we didn't find an expression within parentheses):
    g(s) + O           //   process the remaining expression with g and return O
)(s.split`()`.join`!`) // initial call to F with all strings '()' in s replaced with '!'

मैं सोच रहा था कि आपने [...s.split`()`.join`!`]सिर्फ इसके बजाय क्यों इस्तेमाल किया [...s.replace('()','!')], लेकिन मुझे एहसास हुआ कि यह बिल्कुल वही बाइट-काउंट है .. :)
केविन क्रूज़सेन

@ केविनक्रूजसेन प्राथमिक कारण यह है कि s.replace('()','!')केवल पहली घटना को प्रतिस्थापित करेगा।
अरनुलद

आह, बिल्कुल। जेएस की जगह भूल गए जावा के समान नहीं है। जावा में .replaceसभी घटनाओं को प्रतिस्थापित करता है, और .replaceAllसभी घटनाओं को रीजेक्स सक्षम के साथ बदल देता है। हमेशा सोचा कि जावा में इन दो तरीकों के लिए नामकरण काफी बुरा था, जैसा कि मैंने उन्हें .replaceAllऔर .regexReplaceAllउन रेखाओं के साथ कुछ और कहा होगा , लेकिन मुझे लगता है कि कोडगोल्फ के लिए यह छोटा है .replaceऔर .replaceAll
केविन क्रूज़सेन

1
BTW, मैंने देखा कि आप ~अपने ही जवाब के पहले संस्करण को पोस्ट करने के बाद उसी तकनीक (साथ ) का उपयोग कर रहे थे । महान दिमाग एक जैसा सोचते हैं, मुझे लगता है। : पी
अरनौलड

3

साफ , 415 बाइट्स

import StdEnv,Text
$s#(b,[_:d])=span((<>)' ')(init s)
=join" "(?d++[""<+b])
?[]=[]
?['()':s]=["function returning": ?s]
?['*':s]= ?s++["pointer to"]
?['[':s]#(n,[_:t])=span((<>)']')s
=["array of "<+n: ?t]
?s=case@0s of(['(':h],t)= ?(init h)++ ?t;(h,t)|t>[]= ?h++ ?t=[h<+" is"]
~c=app2((++)[c],id)
@n[c:s]=case c of'('= ~c(@(n+1)s);')'|n>1= ~c(@(n-1)s)=([c],s);_|n>0= ~c(@n s)=span(\c=c<>'('&&c<>'[')[c:s]
@_ e=(e,e)

इसे ऑनलाइन आज़माएं!


3

आर , 225 218 बाइट्स

g=gsub
"&"="@"=paste
"["=function(a,b)a&"array of"&b
"+"=function(a)a&"pointer to"
eval(parse(t=g('\\(\\)','@"function returning"',g('(\\w+) (.*?)([A-Za-z_]\\w*)(.*);','\\2"\\3 is"\\4&"\\1"',g('\\*','+',readline())))))

इसे ऑनलाइन आज़माएं!

पूर्ण कार्यक्रम, एक बार में सभी परीक्षण मामलों के सुविधाजनक परीक्षण के लिए TIO पर एक समारोह में लिपटे।

सबसे पहले, हम regex का उपयोग प्रपत्र के इनपुट में परिवर्तित करने type ...name...;के लिए ..."name is"..."type"()तब फ़ंक्शन संकेतन को उच्च-पूर्ववर्ती संगति संचालक के साथ पाठ में बदल दिया जाता है। दुर्भाग्यवश, हमें भी प्रतिस्थापित *करना होगा +क्योंकि पूर्व एक एकीकृत ऑपरेटर के रूप में स्वीकार्य नहीं है। शेष आर evalओवरलोडेड ऑपरेटरों के साथ किया जाता है ।


1
चतुर समाधान!
जे। डी। ओ।

3

पर्ल 6 , 209 190 171 162 153 बाइट्स

{~({(.[1]Z'is'),.<e>.&?BLOCK,('array of'X .[2]),('function returning','pointer to'Zxx.[3,0])if $_}(m:g/(\*)*[(\w+)+|\(<e=~~>.][\[(\d+).]*(\(.)*/[1]),$0)}

इसे ऑनलाइन आज़माएं!

पुनरावर्ती रेगेक्स दृष्टिकोण। कुछ अतिरिक्त अंतरिक्ष वर्णों का निर्माण करता है जिन्हें 3 बाइट्स की कीमत पर टाला जा सकता है ।

व्याख्या

{     # Anonymous block
 ~(   # Convert list to string
   {  # Block converting a regex match to a nested list
     (.[1]            # Array of 0 or 1 variable names
       Z'is'),        # zipped with string "is"
     .<e>.&?BLOCK,    # Recursive call to block with subexpression
     ('array of'      # String "array of"
       X .[2]),       # prepended to each array size
     ('function returning',  # Strings "function returning"
      'pointer to'           # and "pointer to"
      Zxx             # zipped repetition with
      .[3,0])         # number of function and pointer matches
     if $_            # Only if there's an argument
   }
   (             # Call block
     m:g/        # Input matched against regex
      (\*)*      # Sequence of asterisks, stored in [0]
      [          # Either
       (\w+)+    # the variable name, stored as 1-element array in [1]
       |         # or
       \(        # literal (
         <e=~~>  # the same regex matched recursively, stored in <e>
       .         # )
      ]
      [\[(\d+).]*  # Sequence of "[n]" with sizes stored in [2]
      (\(.)*       # Sequence of "()" stored in [3]
     /
     [1]  # Second match
   ),
   $0     # First match (base type)
 )
}

2

जावास्क्रिप्ट 250 बाइट्स [249?]

यह 250 बाइट्स का उपयोग करता है:

k=>(a=k.match(/\W|\w+/g),s=[v=j=r=""],f=y=>!j&!a[i+1]||(m=a[i],v?(r+=v=m=='['?`array of ${a[i+=3,i-2]} `:m<')'?(i+=2,"function returning "):s[j-1]=='*'?j--&&"pointer to ":""):m==')'?v=j--|i++:m<'+'?s[j++]=a[i++]:r+=a[v=i++]+" is ",f(),r+a[0]),f(i=2))

स्पष्टीकरण:

असल में, यह एक बफर से पढ़ रहा है a, जो एक टोकन इनपुट है। यह लगातार बफर aसे एक स्टैक sतक टोकन ले जाता है , जब तक कि मूल्यांकन मोड चालू न हो जाए। मूल्यांकन मोड पोस्टफ़िक्स संचालन पहले की खपत होगी (), []बफर से, और फिर इसे उपसर्ग ऑपरेटर की खपत होगी *ढेर से। मूल्यांकन मोड चालू हो जाता है जब राज्य वह होता है जहां एक शब्द होता है (या तो टाइपनेम पाया जाता है और भस्म हो जाता है, या एक अंत )पाया जाता है और हटा दिया जाता है)। मूल्यांकन मोड निष्क्रिय है जब कोई और अधिक उपसर्ग / पोस्टफ़िक्स ऑपरेटर नहीं मिलते हैं।

k=>( // k is input
    a=k.match(/\W|\w+/g), // split by symbol or word
    s=[v=j=r=""], // j=0, v=false, r="", s=[]
    // s is the stack, r is the return string,
    // v is true if we're in evaluation mode (Consume (), [], *)
    // v is false if we're waiting to see a ) or token, which triggers evaluation
    // j is the index of the top of the stack (Stack pointer)
    f=y=>!j&!a[i+1]||( // !j means stack is empty, !a[i+1] means we're at the ;
        m=a[i], // Save a[i] in a variable
        v // Are we evaluating?
        ?(
        r+=v=
            m=='[' // Array
            ?`array of ${a[i+=3,i-2]} ` // Skip three tokens: "[", "10", "]"
                                        // a[i-2] is the "10"
            :m<')' // m == '('
                ?(i+=2,"function returning ") // Skip two tokens: "(", ")"
                :s[j-1]=='*' // Stack has a pointer
                    ?j--&&"pointer to " // Pop the stack
                    :"" // Set v to be false, r+=""
        )
        :m==')'
            ?v=j--|i++ // Pop the '(', skip over the ')', v = Evaluation mode
            :m<'+' // m == '*' || m == '('
                ?s[j++]=a[i++] // push(s, pop(a))
                :r+=a[v=i++]+" is " // Otherwise we have the token
        , f(), r+a[0] // Recurse f(), and return r+a[0]. a[0] is the type.
    ),
    f(i=2) // Set i=2, and call f(), which returns the final value r + type
    // a = ["type", " ", ...], so i=2 give the first real token
    // This soln assumes there is only one space, which is an allowed assumption
)

ध्यान दें

अगर मुझे समझ में आया "टोकन के बीच हर जगह एक जगह का उपयोग करें":

k=>(a=k.split(" "),s=[v=j=r=""],f=y=>!j&!a[i+1]||(v?(r+=v=a[i]=='['?`array of ${a[i+=3,i-2]} `:a[i]<')'?(i+=2,"function returning "):s[j-1]=='*'?j--&&"pointer to ":""):a[i]==')'?v=j--|i++:a[i]<'+'?s[j++]=a[i++]:r+=a[v=i++]+" is ",f(),r+a[0]),f(i=1))

तकनीकी रूप से मान्य है, और उपयोग करता है

249 बाइट्स

यह मानते हुए कि हर टोकन के बीच एक जगह है।


2
यह मुझे कई घंटे लग गए, इसके बावजूद यह सीधा लग रहा था। मैंने संभवतः 5-10 बाइट्स / घंटा खटखटाया, जिसकी शुरुआत 350 वर्णों से हुई थी। मेरे पास वास्तव में कोई जीवन नहीं है।
निकोलस पिपिटोन

2
मैं लगभग 325 पर था जब मुझे लगा कि "मैंने अपने वर्तमान एल्गोरिदम के साथ समानता को चीर दिया है - चीर", लेकिन फिर किसी कारण से मैं अभी भी 5-10 / घंटा दस्तक देने में सक्षम था, प्रत्येक दस्तक के बावजूद "ठीक है, यह निश्चित रूप से है ।" इष्टतम परिणाम ”। 250 मारना मनमाना था क्योंकि यह 253 के शासनकाल को हराने वाला पहला था, इसलिए भले ही मैं अभी भी कहता हूं "ठीक है, यह निश्चित रूप से इष्टतम परिणाम है", अभी भी अनुकूलन करने के लिए अधिक हो सकता है।
निकोलस पिपिटोन

1

लाल , 418 410 बाइट्स

func[s][n: t:""a: charset[#"a"-#"z"#"A"-#"Z"#"0"-#"9""_"]parse s[remove[copy x thru" "(t: x)]to a
change[copy x[any a](n: x)]"#"]b: copy[]until[c: next find s"#"switch c/1[#"("[append
b"function returning"take/part c 2]#"["[parse c[remove[skip copy d to"]"(append b
reduce["array of"d])skip]]]#")"#";"[take c c: back back c while[#"*"= c/1][take c
c: back c append b"pointer to"]take c]]s =""]reduce[n"is"b t]]

इसे ऑनलाइन आज़माएं!

स्पष्टीकरण:

f: func [ s ] [
    n: t: 0                                         ; n is the name, t is the type
    a: charset [ #"a"-#"z" #"A"-#"Z" #"0"-#"9" "_" ]; characters set for parsing 
    parse s[                                        ; parse the input with the following rules
        remove [ copy x thru " " ](t: x)            ; find the type, save it to t and remove it from the string
        to a                                        ; skip to the next alphanumerical symbol
        change [ copy n [ any a ] (n: x) ] "#"      ; save it to n and replace it with '#'
    ]
    b: copy [ ]                                     ; block for the modifiers 
    until [                                         ; repeat 
       c: next find s "#"                           ; find the place of the name   
       switch c/1 [                                 ; and check what is the next symbol
           #"(" [ append b "function returning"     ; if it's a '('- it's a function - add the modifier       
                  take/part c 2                     ; and drop the "()"
                ]
           #"[" [ parse c [                         ; '[' - an array
                     remove [ skip copy d to "]"    ; save the number
                             (append b reduce [     ; and add the modifier 
                                  "array of" d
                              ] )                   
                             skip ]                 ; and remove it from the string
                     ]
                ]
           #")"                                     ; a closing bracket 
           #";" [ take c                            ; or ';' - drop it
                    c: back back c                  ; go to the left 
                    while [ #"*" = c/1 ]            ; and while there are '*'
                    [
                        take c                      ; drop them
                        c: back c                   ; go to the left
                        append b "pointer to"       ; add the modifier
                    ]
                    take c                          ; drop '(' (or space)
                 ]
       ]
       s = ""                                       ; until the string is exhausted
    ]
    reduce [ n "is" b t ]                     ; display the resul
]

0

एपीएल (एनएआरएस), चार्ट्स 625, बाइट्स 1250

CH←⎕D,⎕A,⎕a,'_'⋄tkn←nm←∆←''⋄in←⍬⋄⍙←lmt←lin←0
eb←{∊(1(0 1 0)(0 1)(1 0))[⍺⍺¨⍵]}
tb←{x←({⍵='[':3⋄⍵=']':4⋄⍵∊CH,' ':1⋄2}eb⍵)\⍵⋄(x≠' ')⊂x}

gt
tkn←''⋄→0×⍳⍙>lin⋄tkn←∊⍙⊃in⋄⍙+←1⋄→0×⍳(⍙>lin)∨'('≠↑tkn⋄→0×⍳')'≠↑⍙⊃in⋄tkn←tkn,⍙⊃in⋄⍙+←1

r←dcl;n
   n←0
B: gt⋄→D×⍳'*'≠↑tkn⋄n+←1⋄→B×⍳tkn≢''
D: r←ddcl⋄∆←∆,∊n⍴⊂'pointer to '

r←ddcl;q
   r←¯1⋄→0×⍳0>lmt-←1
   →A×⍳∼'('=↑tkn⋄q←dcl⋄→F×⍳')'=↑tkn⋄→0
A: →B×⍳∼(↑tkn)∊CH⋄nm←tkn⋄→F
B: r←¯2⋄→0
F: gt⋄→G×⍳∼tkn≡'()'⋄∆←∆,'function that return '⋄→F
G: →Z×⍳∼'['=↑tkn⋄∆←∆,'array of ',{''≡p←(¯1↓1↓tkn):''⋄p,' '}⋄→F
Z: r←0

r←f w;q
   nm←∆←''⋄in←tb w⋄⍙←1⋄lin←↑⍴in⋄lmt←150⋄gt⋄→A×⍳∼0>q←dcl⋄r←⍕q⋄→0
A: r←nm,' is a ',∆,1⊃in

यह पुस्तक में कोड से सी भाषा से एपीएल के लिए सिर्फ एक traslation है: ब्रायन डब्ल्यू। केर्निघन और डेनिस एम। रिची अध्याय 5.12 द्वारा "लिंगुआगिओ सी"। मैं नहीं जानता कि यह सब कैसे कम किया जाए क्योंकि मैं उस कोड को 100% नहीं समझ पाया था, और क्योंकि मुझे एपीएल पर बहुत अधिक जानकारी नहीं है ... व्यायाम के लिए फ़ंक्शन यह च है; मुझे लगता है कि त्रुटि के लिए केवल 150 नेस्टेड पेरेंटेसिस '(' ')' 'की अनुमति दी जाती है, यदि सभी ठीक हैं तो एक नेगेटिव वैल्यू के साथ एक स्ट्रेंज को लौटा दें। ऐसा लगता है कि यह दूसरे संस्करण की तुलना में बेहतर नहीं है, भले ही कम वर्ण हो क्योंकि दूसरा त्रुटियों को बेहतर तरीके से देखता है। कुछ परीक्षण:

  f 'int f()()'
f is a function that return function that return int
  f 'int a[]()'
a is a array of function that return int
  f 'int f()[]'
f is a function that return array of int
  f 'int i;'
i is a int
  f 'float *f;'
f is a pointer to float
  f 'my_struct_t s[10];'
s is a array of 10 my_struct_t
  f 'int func();'
func is a function that return int
  f 'int arr[3][4];'
arr is a array of 3 array of 4 int
  f 'int (*fptrs[10])();'
fptrs is a array of 10 pointer to function that return int
  f 'float *(*p)[16]; '
p is a pointer to array of 16 pointer to float
  f '_RANdom_TYPE_123 (**(*_WTH_is_TH15)())[1234][567];'
_WTH_is_TH15 is a pointer to function that return pointer to pointe
  r to array of 1234 array of 567 _RANdom_TYPE_123
  f 'uint32_t (**((*(**(((*(((**(*p)))[2]))())))[123])[4])[5]);'
p is a pointer to pointer to pointer to array of 2 pointer to funct
  ion that return pointer to pointer to array of 123 pointer to
   array of 4 array of 5 pointer to pointer to uint32_t
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.