সি প্রিপ্রসেসর তৈরি করুন


18

লক্ষ্যটি হ'ল সি ভাষার জন্য একটি প্রিপ্রসেসর তৈরি করা , আপনার পছন্দের ভাষায় বাইটগুলিতে উত্স কোডের আকারের ক্ষেত্রে যতটা সম্ভব ছোট । এর ইনপুটটি কোনও সি উত্স ফাইল হবে এবং এর আউটপুটটি প্রাক-প্রক্রিয়াজাত উত্স কোড হবে।

যে আইটেমগুলির এটি প্রক্রিয়া করতে সক্ষম হবেন তা হ'ল : মন্তব্য অপসারণ (লাইন / ব্লক), # নির্দেশাবলী অন্তর্ভুক্ত করুন ( আপেক্ষিক পথে ফাইলগুলি খোলার মাধ্যমে এবং প্রয়োজনীয় বিন্দুতে পাঠ্য প্রতিস্থাপনের মাধ্যমে), # সংজ্ঞা, # অপরিবর্তিত, # আইফ, #elif, #else, #endif, #ifdef, #ifndef, এবং সংজ্ঞায়িত ()। অন্যান্য সি প্রিপ্রসেসর নির্দেশিকাগুলি যেমন # প্রাগমাস বা # ত্রুটিগুলি উপেক্ষা করা যেতে পারে।

# যদি নির্দেশিকায় গাণিতিক এক্সপ্রেশন বা তুলনা অপারেটরগুলি গণনা করার দরকার নেই, আমরা ধরে নিই যে অভিব্যক্তিটি শূন্য ব্যতীত কোনও পূর্ণসংখ্যার (যতক্ষণ না এর মূল ব্যবহারটি সংজ্ঞায়িত () নির্দেশকের জন্য থাকবে) ততক্ষণ সত্য হিসাবে মূল্যায়ন করবে। সম্ভাব্য ইনপুট এবং আউটপুট অনুসরণের উদাহরণ (আউটপুট ফাইলগুলিতে সম্ভাব্য অতিরিক্ত হোয়াইটস্পেসগুলি আরও ভাল চেহারার জন্য ছাঁটাই করা হয়েছিল, আপনার কোডটি এটি করার দরকার নেই)। নিম্নলিখিত উদাহরণগুলি সঠিকভাবে প্রক্রিয়া করতে সক্ষম একটি প্রোগ্রাম যথেষ্ট বিবেচিত হবে।

----Input file: foo.c (main file being preprocessed)

#include "bar.h" // Line may or may not exist

#ifdef NEEDS_BAZZER
#include "baz.h"
#endif // NEEDS_BAZZER

#ifdef _BAZ_H_

int main(int argc, char ** argv)
{
    /*  Main function.
        In case that bar.h defined NEEDS_BAZ as true,
        we call baz.h's macro BAZZER with the length of the
        program's argument list. */
    return BAZZER(argc);
}

#elif defined(_BAR_H_)

// In case that bar.h was included but didn't define NEEDS_BAZ.
#undef _BAR_H_
#define NEEDS_BARRER
#include "bar.h"

int main(int argc, char ** argv)
{
    return BARRER(argc);
}

#else

// In case that bar.h wasn't included at all.
int main()
{return 0;}

#endif // _BAZ_H_

----Input file bar.h (Included header)

#ifndef _BAR_H_
#define _BAR_H_

#ifdef NEEDS_BARRER

int bar(int * i)
{
    *i += 4 + *i;
    return *i;
}

#define BARRER(i) (bar(&i), i*=2, bar(&i))

#else
#define NEEDS_BAZZER // Line may or may not exist
#endif // NEEDS_BARRER

#endif // _BAR_H_

----Input file baz.h (Included header)

#ifndef _BAZ_H_
#define _BAZ_H_

int baz(int * i)
{
    *i = 4 * (*i + 2);
    return *i;
}

#define BAZZER(i) (baz(&i), i+=2, baz(&i))

#endif // _BAZ_H_

----Output file foopp.c (no edits)

int baz(int * i)
{
    *i = 4 * (*i + 2);
    return *i;
}

int main(int argc, char ** argv)
{
    return (baz(&argc), argc+=2, baz(&argc));
}

----Output file foopp2.c (with foo.c's first line removed)

int main()
{return 0;}

----Output file foopp3.c (with bar.h's line "#define NEEDS_BAZZER" removed)

int bar(int * i)
{
    *i += 4 + *i;
    return *i;
}

int main(int argc, char ** argv)
{
    return (bar(&argc), argc*=2, bar(&argc));
}

আপনি কি ইনপুট / আউটপুট নমুনা সরবরাহ করতে পারেন?
ফ্লোরেন্ট

আমাদের একটি পরীক্ষার কোড সরবরাহ করুন। উদাহরণ ছাড়া এটি প্রায় অসম্ভব।
ইসমাইল মিগুয়েল

আহ, আমি করব। একটু ধৈর্য ধরুন কারণ সময় এবং কাজের চাপের কারণে আমি খুব দ্রুত হতে পারি না।
থানাসিস পাপআউটসাইডাকিস

1
কতটুকু #ifসমর্থন করা দরকার? অর্থাত্ প্রিপ্রোসেসরের গাণিতিক, বিটওয়াইজ অপারেশন ইত্যাদির সাহায্যে অভিব্যক্তি সমর্থন করা দরকার?
হাস্তুরকুন

ঠিক আছে, উদাহরণস্বরূপ ইনপুট / আউটপুট এবং আরও ব্যাখ্যা যুক্ত করা হয়েছে
থানাসিস পাপআউটসাইডাকিস

উত্তর:


8

ফ্লেক্স, 1170 + 4 = 1174

সংকলন পতাকার জন্য ফ্লেক্স কোড + 4 টি অক্ষরে 1170 টি অক্ষর। এক্সিকিউটেবল উত্পাদন করতে, চালান flex pre.l ; gcc lex.yy.c -lflএন্ট্রি একটি চালুনির মতো মেমরি ফাঁস করে এবং অন্তর্ভুক্ত ফাইলগুলি বন্ধ করে না। তবে অন্যথায়, এটি অনুমান অনুসারে সম্পূর্ণ কার্যকরী হওয়া উচিত।

%{
#define M malloc
#define X yytext
#define A a=X
#define B(x) BEGIN x;
#define Y YY_CURRENT_BUFFER
*a,*b,**v,**V,**t,**T,i,s=1,o;
g(){t=M(++s);T=M(s);for(i=1;i<s-1;i++)t[i]=v[i],T[i]=V[i];free(v);free(V);v=t;V=T;}
f(){for(i=1;i<s;i++)if(!strcmp(v[i],a))return i;return 0;}
d(y){X[yyleng-y]=0;}
%}
%x D F I
N .*\n
%%
"//".*
"/*"([^\*]|\*[^\/])*"*/"
\"(\\.|[^\\"])*\" ECHO;
^"#include "\"[^\"]*\" d(1),yypush_buffer_state(yy_create_buffer(fopen(X+10,"r"),YY_BUF_SIZE));
^"#define "[^ ]* {B(D)strcpy(a=M(yyleng),X+8);}
<D>" "?{N} {b=M(yyleng);d(1);f(strcpy(b,X+(X[0]==32)))?free(V[i]),V[i]=b:g(),v[s-1]=a,V[s-1]=b;B(0)}
^"#undef "{N} d(1),v[f(A+7)][0]=0;
^"#if defined(".*")\n" h(2,12);
^"#ifdef "{N} h(1,7);
^"#if "{N} {d(1);if(!atoi(X+4))B(F)}
^"#ifndef "{N} {d(1);if(f(A+8))B(F)}
<F>^"#if"{N} o++;
<F>^"#endif"{N} if(!o--)B(++o)
<F>^"#else"{N} if(!o)B(0)
<F>^"#elif defined(".*")\n" if(!o){d(2);if(f(A+14))B(0)}
<F>^"#elif "{N} if(!o){d(1);if(atoi(X+6))B(0)}
<F>{N}
^"#endif"{N}
^"#el"("se"|"if"){N} B(I)
<I>^"#endif"{N} B(0)
<I>{N}
[a-zA-Z_][a-zA-Z_0-9]* printf(f(A)?V[i]:a);
<<EOF>> {a=Y;yypop_buffer_state();if(!Y)exit(0);fclose(a);}
%%
h(x,y){d(x);if(!f(A+y))B(F)}

কিছু ব্যাখ্যা:

  • aএবং bইনপুট থেকে স্ট্রিং রাখা টেম্পস হয়। aফাংশন পরামিতি হিসাবে ব্যবহৃত হয় f
  • vম্যাক্রোগুলির নাম ধারণ করে এবং ম্যাক্রোগুলির V'ভি'লিউস ধরে রাখে
  • tএবং Tহয় 'যখন আমরা হত্তয়া জন্য t'emporary হোল্ডার vএবংV
  • i লুপগুলির জন্য একটি 'আইক্রিমেন্টার'
  • s ম্যাক্রো অ্যারের 'সাইজ'
  • oifএকটি মিথ্যা শর্তসাপেক্ষে 'ওপেন' এর গণনা
  • g() 'ম্যাক্রো অ্যারেগুলিকে গুরো করে
  • f()' vহিসাবে একই মান সহ একটি ম্যাক্রো ফিন্ড করেa
  • d(y)yবর্তমান ইনপুট থেকে সর্বশেষ অক্ষরগুলিকে 'ডি' ছড়িয়ে দেয়
  • রাষ্ট্র Dএকটি 'ডি'ফিনের অভ্যন্তরের জন্য
  • রাষ্ট্র Fএকটি 'F'alse শর্তসাপেক্ষে উপেক্ষা করার জন্য
  • রাষ্ট্র I'I'gnoring জন্য else/ elifপরে একটি সত্য শর্তসাপেক্ষ পাওয়া যায়নি।

EDIT1: অনেকগুলি মেমরি ফাঁস পরিষ্কার করে এবং ফাইল ক্লোজিং প্রয়োগ করে

EDIT2: নেস্টেড ম্যাক্রোগুলি আরও সঠিকভাবে পরিচালনা করতে সংশোধিত কোড

সম্পাদনা 3: গল্ফিংয়ের পাগল পরিমাণ

EDIT4: আরও গল্ফিং

EDIT5: আরও গল্ফিং; আমি আরও লক্ষ্য করেছি যে fclose () এ আমার কল কিছু কম্পিউটারে সমস্যা সৃষ্টি করে ... এটি খতিয়ে দেখছে।


এটি এখন পর্যন্ত বেশিরভাগ ক্ষেত্রে খুব ভালভাবে কাজ করে ... কোনও কারণে যখন আমি #includeস্টাফ করি তখন সেগমেন্টেশন ত্রুটি নিক্ষেপ করে , তবে আমার ধারণা এটি সম্পাদনা # 5 এর বাগের সাথে সম্পর্কিত। এছাড়াও এটি ম্যাক্রোগুলিকে প্রতিস্থাপন করে না, যদিও এটি সফলভাবে # আই ব্লকগুলি প্রক্রিয়া করে - যদি না আমি কিছু ভুল করি ... তবে সাধারণভাবে এটি খুব ভাল দেখায়, এবং এটি কোনও লেক্সার কী করতে পারে তার একটি মোটামুটি ধারণা দেয় আমি এটির গল্ফযুক্ত আকারেও বুঝতে পারি। কোডগুলি ঠিকঠাকভাবে ব্যাখ্যা করার সাথে সাথে বাগগুলি ঠিক করা যায় কিনা তা দেখার চেষ্টা করুন, অন্য কোনও এন্ট্রি না থাকায় সম্ভবত এটি উত্তর চয়ন করা হবে।
থানাসিস পাপআউটসাইডাকিস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.