# مباحث متفرقه برنامه نویسی > پروژه‌های Open Source > حرفه ای: ساخت Compiler و یک زبان برنامه نویسی جدید

## IamOverlord

سلام دوستان،
برای ساخت یک زبان برنامه نویسی جدید و در اصل یک Compiler کسی هست که با هم همکاری کنیم؟

----------


## Hossenbor

اگه یک کاربر بیسواد میخوایی من حاضرم دوسته عزیز من این ایده تو رو داشتم ولی هدفم یک مترجم برای برنامه سی پلاس پلاس بود این پروژه ام کاری نمی کرد فقط کارش این بود که دستور زبانه منو به سی پلاس پلاس تغییر بده و دستور زبانم هم سی شارپ بود تقریبا

----------


## TRex2000

منم هستم 
فقط یه کم بیشتر توضیح بده

----------


## Asg.Mojtaba

اینکه از پایه زبان رو بسازید احتیاج به مطالعه بسیار زیاد داره و همچنین انگیزه.
حواستون باشه چیز با ارزشی به نام زمان وجود داره ، سوال اصلی اینجاست آیا واقعا ما به زبان جدید نیاز داریم.یا به عبارت دیگر چه نیازی هست که باید براش زبان برنامه نویسی درست کنیم.

اما نوشتن یک مفسر بسیار راحتر از نوشتن یک کامپایلر خواهد بود ، مثلا مفسری که یک قالب ساده که بسیار شبیه محاوره هست رو به کد سی پلاس پلاس تبدیل کنه و بعد از اون از طریق خود سی پلاس پلاس کامپایل کندش.

به هر حال در کنار شما خواهم بود چون مطالب جالبی رو یاد خواهیم گرفت.

----------


## IamOverlord

هدف این بود که VB6 زنده بشه،
شی گرایی به طور کامل اضافه بشه و ...
البته منظورم تغییر VB6 نیست. منظورم اینه که از پایه این کارو انجام بدیم و کد هامون رو به کد Assembly تبدیل کنیم.
در مورد دانش این کار هم نگران نباشید.
قبلا به طور عملی، تجربه ی این کارارو داشتم... فقط این کار وقت و حوصله نیاز داره، که به نظرم گروهی باشه بهتره.

----------


## amin32

به نظر من اگه واقعآ قصد چنین کاری رو دارید باید به شکل اصولی پیش برید.یعنی اولآ کامپایلر باید به دو قسمت جلوبندی و عقب بندی تقسیم بشه. دومآ در جلوبندی باید فازهای تحلیلگر لغوی , تحلیلگر نحوی و معنایی رو به شکل استاندارد پیاده سازی کنید ( مثل همه کاپایلر ها). اگه توضیحات بیشتری خواستید در خدمتم.

----------


## IamOverlord

برای ایجاد تحلیل گر، چه کار کنیم؟
خودمون بنویسیم؟ یا از نرم افزار استفاده کنیم؟
و اگه از نرم افزار، چه نرم افزاری؟

----------


## amin32

> برای ایجاد تحلیل گر، چه کار کنیم؟
> خودمون بنویسیم؟ یا از نرم افزار استفاده کنیم؟
> و اگه از نرم افزار، چه نرم افزاری؟


برای تحلیلگر لغوی میتونید از flex و برای تحلیلگر نحوی از bison یا yacc استفاده کنید. کار این ابزارها به این شکل هست که شما مشخصات لغوی یا نحوی زبانتون رو با یک زبان مخصوص این ابزارها تعریف میکنید و این ابزارها تحلیلگر رو به زبان c یا پاسکال (معمولا) براتون ایجاد میکنند. اما اگه از من بپرسید میگم تحلیلگرها رو خودتون بنویسید چون انعطاف پذیریش خیلی میره بالا.
من نمیدونم اطلاعاتتون در مورد کامپایلر چقدره اگه خواستید میتونم از ابتدا براتون توضیح بدم.

----------


## IamOverlord

خیلی ممنون از پاسختون.  :قلب: 
فکر نمی کنم از اوّل لازم باشه... اطلاعات تا حدی دارم که راحت صحبت کنیم.
به نظر من هم خودمون بنویسیم بهتره...
اما در مورد این که خودمون بنویسیم، با چه زبانی؟ با چه Method ای؟ ...

----------


## amin32

اکه سرعت براتون مهم نباشه فاز جلو بندی رو میتونید با هر زبانی پیاده سازی کنید ولی احتمالا تو فاز عقب بندی (به خاطر تولید کد ) نمیتونید روی هر زبانی حساب باز کنید.
اگه شما با فازها و زیر فازهای کامپایلر و کاربردشون آشنا نیستید میتونم براتون توضیح بدم. من اطلاعاتم بیشتر در فاز جلوبندی هست. یعنی تا جایی که بتونید یه
مفسر بنویسید.وقتی حرف از کاپایلر میشه معمولا شما باید بتونید برای سیستم عامل مورد نظر یه برنامه اجرایی تولید کنید.که من اطلاعات زیادی در این مورد ندارم. ولی در مفسر شما 
فقط فاز جلوبندی و زیر شاخه های اونو دارید.و در آخر کد میانی تولید شده رو مستقیم اجرا میکنید.
در کل فکر میکنم c یا ++c برای ایجاد کامپایلر مناسب باشه. ولی مفسر رو میتونید از هر زبانی استفاده کنید.البته باید به سرعت اجرا دقت کنید.

----------


## IamOverlord

سرعت برام مهم نیست.
در مورد تولید کد اجرایی، کدمون رو به کد Assembly تبدیل می کنیم و با Flat Assembler فایل اجرایی می گیریم. ضمنا FASM رو برای این گفتم که هم Open Source هست، هم این که باهاش برنامه های Windows و DOS بلدم بنویسم.
به غیر از مرحله تولید کد اجرایی و Assemble کردن و LINK کردن، در مورد مراحل قبلیش یه توضیح مختصر بدی که می خوایم چی کار کنیم ممنون می شم.

----------


## amin32

امیدوارم ازم ناراحت نشی , اصلآ قصدم نصیحت نیست.میخوام یکم منطقی باشی... ساخت کامپایلر و یه زبان جدید کار با ارزشیه. کسانی که موفق به انجام این کار شدن از علم بالایی برخوردار بودند.
حداقل کاری که باید انجام بدی اینه که یه کتاب در مورد اصول طراحی کامپایلر و همچنین نظریه زبانها و ماشینها بخونی. فکر میکنم این در مقابل کاری میخوای انجام بدی بهای کمی باشه.
خب سعی میکنم در مورد کامپایلر یه توضیح مختصر و مفید بدم که شاید کسانی که هیچی در موردش نمیدونن هم چیزی عایدشون بشه.
مراحل کامپایل: در کل کامپایلر به دو فاز جلوبندی و عقب بندی تقسیم میشه. هر کدوم از این فازها هم به فازهای کوچکتر تقسیم میشن.
مراحل جلو بندی:
۱-تحلیلگر لغوی: این تحلیلگر کارش اینه که تک تک لغات برنامه زبان مبدآ رو بررسی میکنه و نوعشون رو مشخص میکنه(شناسه,کلمه کلیدی,عملگر و...) و همچنین چک میکنه که آیا این لغت جزء زبان هست یا نه و اگر نباشه خطای لغوی رخ داده.(مثلا در اکثر زبانها نام متغییرها نمیتونن با عدد شروع بشن.) برای ایجاد تحلیلگر لغوی باید DFA های مربوط به انواع لغات زبانتون رو به شکل تابع پیاده سازی کنید و هر لغت برنامه ورودی رو با همشون چک کنید تا نوعش مشخص بشه.DFA و زبانهای باقاعده رو نمیشه اینجا توضیح داد ولی فقط بگم از مباحث اصلی نظریه زبانهاست.در آخر باید لغات به همراه نوعشون برای فاز بعدی یعنی تحلیلگر نحوی فرستاده بشه.

۲-تحلیلگر نحوی: به زبان ساده درستی ترتیب لغات در کنار هم رو بررسی میکنه. برای مثال در زبان پاسکال یک برنامه باید به این شکل شروع شود:
نام برنامه    program
تعریف متغیرها
و باقی برنامه....

حالا اگر برنامه را به این شکل بنویسیم:
program نام برنامه
تعریف متغیرها
و باقی برنامه....

یا حتی:
تعریف متغیرها
نام برنامه program
و باقی برنامه....

در این حالات خطای نحوی رخ داده.در واقع کار تحلیلگر نحوی اینه که بعد از بررسی ترتیب لغات از ساختار برنامه یه درخت به نام درخت تجزیه به عنوان خروجی ایجاد کنه و برای فاز دیگه بفرسته.برای پیاده سازی
تحلیلگر نحوی باید از گرامرهای مستقل از متن استفاده کنید.که اونم توضیحش مفصل و در نظریه زبانها و ماشینها در موردش صحبت شده.

و اینجاست که میفهمیم چرا علمی به نام علوم کامپیوتر پایه گذازی شد!!!!

۳-تحلیلگر معنایی
۴-تولید کننده کد میانی

این دوتا فاز و همچنین عقب بندی بمونه برای بعد. :لبخند:

----------


## IamOverlord

نه ناراحت نمی شم، 
اتفاقا از رو کتاب می رم جلو
ولی این قدر تئوریه که بعضی جاهاش گنگ می شه...

----------


## amin32

الان دقیقا کجاهاش برات گنگه؟

----------


## IamOverlord

یه درخت تجزیه رو به چه صورت باید ذخیره کنیم که بهمون کمک کنه؟

----------


## amin32

والا دانش اندک و ناقص من میگه که این بیشتر به زبان برنامه نویسی مورد استفاده مربوط میشه.
حالا تو در مراحل قبلی یعنی تحلیلگر لغوی که مشکلی نداری. اگه ابهامی هست بگو. چون من تصمیم دارم یک تحلیلگر لغوی ساده بنویسم.البته اگه بتونم. :قهقهه:

----------


## IamOverlord

نه با تحلیلگر لغوی مشکل خاصی ندارم. بعدشم ما می خوایم طعم این کارو بچشیم، کار تجاری که نمی خوایم بکنیم. امتحانش ضرر نداره.
ببین واسه شروع یه کار ساده می گم.
خط به خط برنامه رو جدا می کنیم تو یه آرایه.
بعد هر خط رو بر اساس فواصل بین کلمات و عبارات جدا می کنیم.
فقط توجه می کنیم که این کارو برای عبارات داخل کوتیشن انجام ندیم.
... ؟  :متفکر:

----------


## IamOverlord

... این کار برای ساختار های چند خطی یا تو در تو جواب نمی ده یا خیلی سخته.
چون ما داریم هر خط رو به تنهایی بر رسی می کنیم.
البته می شه یه کاری کرد.
این که بیایم تعیین کنیم الان تو چه ساختاری هستیم، ساختار For، ساختار While، ...
اما اگه به پایان ساختار فعلی رسیدیم، باید بفهمه ساختار فعلی، خودش جزو کدوم ساختار بوده، یعنی ساختار قبلی چی بوده.
چون ممکنه برنامه نویس چند تا For تو در تو داشته باشه یا ...
پس می شه یه متغیر رشته ای در نظر گرفت که وقتی وارد ساختار جدید می شیم، مشخصه ی اون ساختار بهش اضافه می شه و وقتی می آیم بیرون از ساختار، آخرین ساختار ثبت شده از متغیر حذف می شه.
نظر شما چیه؟  :متفکر:

----------


## amin32

ببخشید ولی فکر میکنم جدا کردن لغات جزء تحلیلگر لغویه و جدا کردن کدها به شکل خط به خط یا ';' یا تگ و ....  کار تحلیلگر نحویه و با این کار با هم تداخل پیدا میکنند.
پیشنهاد من اینه که اول از تحلیلگر لغوی شروع کنیم.برای شروع هم من دارم یک تحلیلگر ساده مینویسم که لغات رو از هم جدا میکنه و شناسه ها و اعداد ثابت رو تشخیص میده.
البته با وی بی مینویسم ولی بعدآ در صورت لزوم میتونم با c هم بنویسم.

----------


## amin32

> پس می شه یه متغیر رشته ای در نظر گرفت که وقتی وارد ساختار جدید می شیم، مشخصه ی اون ساختار بهش اضافه می شه و وقتی می آیم بیرون از ساختار، آخرین ساختار ثبت شده از متغیر حذف می شه.
> نظر شما چیه؟


این تو رو یاد چیزی نمیندازه؟؟؟

*پشته*....  یو ها ها ها ها .......  :قهقهه:  :شیطان: 

فکر میکنم اول باید به زیربنا توجه کنیم.این مسائل چیزی نیست که اول کار به فکرشون باشیم. راستی هنوز ساختار و نحو دستورات زبان مشخص نیستند.

----------


## IamOverlord

عیب نداره. چون پردازش رشته می کنیم، فعلا با VB6 راحت تریم.
راستی یه برنامه ای هم گذاشتم ببین، با همین VB6 نوشته شده:

----------


## IamOverlord

> این تو رو یاد چیزی نمیندازه؟؟؟
> 
> *پشته*....  یو ها ها ها ها ....... 
> 
> فکر میکنم اول باید به زیربنا توجه کنیم.این مسائل چیزی نیست که اول کار به فکرشون باشیم. راستی هنوز ساختار و نحو دستورات زبان مشخص نیستند.


آه... آره چه قدر خودمو عذاب دادم، یهو می نوشتم Stack دیگه...!

الان ساختار و نحو رو مشخص کنیم اول؟ نظری داری؟  :متفکر:

----------


## amin32

> الان ساختار و نحو رو مشخص کنیم اول؟ نظری داری؟


خب آره . فکر میکنم برای اینکه بتونیم به طور جدی کار رو شروع کنیم باید ساختار نحوی زبانمون مشخص باشه . ولی فکر میکنم نیازه که اول یه تحلیلگر لغوی ساده رو به صورت آزمایشی ایجاد کنیم.
من میتونم روی اون کار کنم و شما هم در این فرصت روی ساختار زبان فکر کنی.

----------


## IamOverlord

ببین زبان های جورواجور با Syntax های عجیب و غریب و بعضا جالب خیلی هست. اما من به نظرم به جای این که یه Syntax کاملا جدید درست کنیم، همین Syntax زبان BASIC رو استفاده کنیم.
چون می خوایم باهاش Win32 Application نوشته بشه، به نظرم رو VB Classic تمرکز کنیم بهتر باشه. اما با ایده های جدید خودمون و یه سری تغییرات جالب.
به نظرم خیلی عالی می شه اگه VB6 رو احیا کنیم.
نظرت چیه؟

----------


## IamOverlord

به این لینک نیگا بنداز، می تونی ایده بگیری : groups.engin.umd.umich.edu/CIS/course.des/cis400/index.html

----------


## amin32

> ببین زبان های جورواجور با Syntax های عجیب و غریب و بعضا جالب خیلی هست. اما من به نظرم به جای این که یه Syntax کاملا جدید درست کنیم، همین Syntax زبان BASIC رو استفاده کنیم.
> چون می خوایم باهاش Win32 Application نوشته بشه، به نظرم رو VB Classic تمرکز کنیم بهتر باشه. اما با ایده های جدید خودمون و یه سری تغییرات جالب.
> به نظرم خیلی عالی می شه اگه VB6 رو احیا کنیم.
> نظرت چیه؟



نظرت قابل احترامه ولی انصافآ این که ما بیایم یک زبان (vb) رو در یک محیط (win32) از نو بسازیم یکم کار بیهوده ای به نظر میاد.من نظرم اینه که یا یک زبان جدید رو برای win32 بسازیم یا اینکه یک زبان مثل vb رو برای محیطی جدید ایجاد کنیم.

----------


## IamOverlord

باشه.
برای چه محیطی منظورت هست؟
البته بیهوده هم نیست، چون الان VB6 دیگه از دور خارج شده، قرار هم نیست کار تکراری کنیم و عین VB6 رو بسازیم.
ولی خوب نظر شما چیه؟

----------


## amin32

منظورم از محیط جدید محیطهایی هست که مثلا زبان vb به اون اندازه در اونها توسعه پیدا نکرده.مثل لینوکس, اندروید و .... البته منظورم
ساخت برنامه اجرایی از کد هست نه ساخت کامپایلر برای اون محیطها. اما در کل ساخت یک زبان جدید رو جالبتر میدونم.

راستی تونستم یک تحلیلگر لغوی ساده طراحی کنم.این تحلیلگر اعداد و شناسه ها رو تشخیص میده و لغات دیگر رو خطا میگیره  :لبخند گشاده!: 

Lexical Analyzer.zip

----------


## IamOverlord

ای ول، خیلی کارت درسته!  :قلب: 
آخه می دونی، من که فعلا از محیط های دیگه اطلاع کافی ندارم...
می تونیم از Windows شروع کنیم و به اونا هم برسیم...

یه فکری به نظرم رسید:
الان برای شروع بیا یه کار خیلی سریع تر و ساده تر کنیم،
فقط برای محیط Console برنامه بنویسه...
ضمنا برنامه های Console در Windows دو نوع هستند.
یه سری با وقفه ها نوشته شدن و در سیستم عامل های دیگه هم می تونن کار کنن،
و یه سری با توابع API نوشته شدن و فقط در Windows کار می کنند.

این نوع دوم رو بعدا می شه گسترش داد به برنامه های غیر Console ای که حالت گرافیکی Windows رو دارن.

حالا به نظر خودت چه زبانی رو برای Windows بنویسیم که هم بیهوده نباشه، هم جذابیت داشته باشه؟

----------


## amin32

شاید دیگه بهم بگی عجب کلیدی هستی تو... ولی باز به نظر من یک زبان جدید میتونه جالبتر باشه.میتونیم با هم فکر کنیم و ساختارهای جالبی رو بسازیم. فکر نمیکنم اونقدر سخت باشه.
راستش وقتی خودم رو جای کسی که با زبان ما (vb توسعه داده شده) برخورد میکنه میگذارم یه خورده نسبت بهش بی تفاوتم.خصوصآ با وجود چارچوب دات نت.ولی باز مشورت شرط عقل است.
در ضمن به نظر من محیط کنسول یا گرافیکی  هر دو خوبن و برام فرقی نمیکنه.

----------


## IamOverlord

باشه.
اتفاقا از کارهای تازه و خیس خوشم می آد!  :لبخند گشاده!:   :قلب: 
اولا که این مشخص بشه : برای Windows برنامه می نویسه دیگه؟ منظورم اینه که تحت چارچوب Console و DOS نباشه دیگه؟

----------


## amin32

> باشه.
> اتفاقا از کارهای تازه و خیس خوشم می آد!  
> اولا که این مشخص بشه : برای Windows برنامه می نویسه دیگه؟ منظورم اینه که تحت چارچوب Console و DOS نباشه دیگه؟


اگه موافق باشی فعلا مبتنی بر کنسول کار کنیم.چون برای ویندوز مجبوریم در همین ابتدا روی شی گرایی و ارتباط با کنترلها کار کنیم. که یکم کارو پیچیده میکنه.

----------


## IamOverlord

موافقم.
با استفاده از وقفه (Interrupt) ها یا با استفاده از توابع API؟
من با دومی موافقم.

----------


## amin32

> موافقم.
> با استفاده از وقفه (Interrupt) ها یا با استفاده از توابع API؟
> من با دومی موافقم.


هر کدوم که کار رو ساده تر میکنند. ظاهرآ api سادهتره .منم موافقم.
فقط من دوست ندارم بد قول باشم.این کار رو یه کار علمی بدونیم. هر زمانی ممکنه من یا شما نتونیم کارو ادامه بدیم.

----------


## IamOverlord

من هم دقیقا حس شما رو دارم، لازم نیست گیر سه پیچ بدیم در عوض از کار لذت می بریم...

اتفاقا Interrupt ها ساده ترند.

ولی برای روش دوم یعنی استفاده از توابع API این مرجع MSDN هست که توابع API و Structure ها و Event های مربوطه رو توضیح داده.

در مورد Interrupt ها هم این جا رو ببینید : www.ctyme.com/intr/int.htm

می خواستم یه لینک به این جا رم بدم، ولی مثل این که امشب یه خبرایی هست!!! : www.sopastrike.com

----------


## amin32

خب پس بهتر کم کم به فکر ساختار زبان باشیم.

----------


## IamOverlord

بالاخره از یه جایی باید شروع کرد دیگه، ایده های کوچیک و بزرگ....

مثلا طرف بنویسه :

f(x) = x ^ 2

و کارش اینه که این مدل کدها رو :

f(35)

تبدیل به این مدل کد ها می کنه:

35 ^ 2

یعنی طرف به سادگی و به طور صریح Function تعریف می کنه (جدا از اون Function هایی که مثل زیربرنامه ها هستند و اجرا می شن)

حتی می تونه یه همچین توابعی هم داشته باشه:

Zarb3Ta(a,b,c) = a * b *c

----------


## IamOverlord

برای توابع بازگشتی این کارو می تونه بکنه :

phibonacci(n)
{
   n = 1 : 1
   n = 2 : 1
   n > 2 : phibonacci(n-1) + phibonacci(n-2)
}

این کار جنبه ی ریاضی و قشنگ تری به کد می ده... :متفکر: 

مثلا تابع قدر مطلق رو این طوری می تونه تعریف کنه :

Absolute(x)
{
   n => 0 : x
   n < 0 : -x
}

----------


## amin32

ایده هات عالی بود. :تشویق:  ولی بهتره اول به مسائل اساسی تر فکر کنیم.مثل چگونگی شروع و پایان برنامه-تعریف متغییرها-چگونگی استفاده از عملگرها و...

----------


## IamOverlord

برنامه ها sub main داشته باشن یا نه؟
کلمات کلیدی function و sub رو تعریف کنیم؟ یا مثل زبان C نوع خروجی رو پشت اسم زیربرنامه بنویسیم؟
بدون تعریف متغیر ها می شه ازشون استفاده کرد؟

در مورد عملگر ها به نظرم توان رو به عنوان عملگر در نظر بگیریم، نه مثل زبان C به صورت یه تابعی مثل ()pow

+
-
*
/
^
\
mod ...؟

انتساب ها:

= یا =: ؟
=+
=-
=*
=/
=\  ...؟
=^ ...؟

----------


## amin32

ایده های من

دستورات با \ یا - از هم جدا بشن.

جایگزینی و انتساب:
a:b

ولی برای تست تساوی در دستورات شرطی از = استفاده بشه.

+
 -
 *
 /

اما برای توان و باقیمانده از یک کلمه کلیدی استفاده بشه.

یک تابع main داشته باشیم

از < و > برای بلاک بندی توابع استفاده کنیم.

فعلآ همین. اگه نظری داری بگو.

----------


## IamOverlord

خوب با main موافقم، چون می شه از طریق خط فرمان به برنامه آرگومان ارسال کرد.
2 تا چیز در زبان C هست که گاهی اذیت می کنند:          ;           {}
راحت تره که برای پایان دستوارت از ; استفاده نکنیم. اما اگه خواستیم چند تا دستور رو تو یه خط بنویسیم ; بذاریم. چون مفهوم مرتبطی داره. وقتی یه جمله ای می نویسیم که با جمله ی بعدی مرتبطه از ; استفاده می کنیم، در برنامه نویسی هم خطوط برنامه با هم مرتبط هستند پس فکر کنم بهتر باشه از ; استفاده کنیم برای نوشتن چند خط کد در یک خط.

برای تست تساوی موافقم از = استفاده کنیم نه مثلا ==.
چون اول ها که برنامه نویسی یاد گرفته بودم، 2 معنی متفاوت = در شرط ها و انتساب ها برام نا آشنا بود.

یه ویرایش کوچولو می کنم ببینم موافقی:
=: برای تساوی (گذاشتن ':' از لحاظ مفهومی واقعا مناسبه)

به جای mod (مثل BASIC)، % (مثل C) بذاریم بهتر نیست؟
برای توان چی؟
از ^ که در BASIC هست استفاده کنیم
یا تابع بسازیم : ()pow
یا ... ؟

< و > برای بلاک بندی توابع ریاضی یا اجرایی؟

----------


## amin32

جدا کردن دستورات بر اساس خط به خط و بدون علامت هماهنگ کننده ( ; یا \ یا هر چیزی ) رو میشه تا حدودی حل کرد. ولی به هر حال نمیشه از بلاک بندی گذشت. چون اکثر زبانهای معروف
حتی ویژوال بیسیک هم به نحوی این کار رو انجام میدن (sub .... end sub). ایدت در مورد استفاده از علامت ; فقط برای جدا کردن دستورات در یک خط هم جالبه اما بهتره از یه علامت دیگه
استفاده کنیم که شبیه زبانهای دیگه نشه. مثل \ یا |

----------


## amin32

البته منظورم از بلاک بندی , بلاک بندی تمام توابع هست (مثل {} در C)
برای توان هم بهتره تابع بسازیم و از تابع به عنوان کلمه کلیدی استفاده کنیم.




> یه ویرایش کوچولو می کنم ببینم موافقی:
> =: برای تساوی (گذاشتن ':' از لحاظ مفهومی واقعا مناسبه)


متوجه نشدم بالاخره برای انتساب از ':' استفاده کنیم یا از =:

----------


## IamOverlord

از =: استفاده کنیم. چون : مفهموم توضیح در مورد یه چیزی رو می ده (یه ایده در این مورد همین الان به ذهنم رسید)، و = مشخص می کنه که توضیح ما در مورد برابر شدن هست.
این ساختار رو نگاه کن:

a := b    'yani a = b
a :- b    'yani a = a - b
a :+ b    'yani a = a + b
a :* b    'yani a = a * b
a :/ b    'yani a = a / b
' ...
' shabihe += va -= ...

از : خالی می تونیم برای تعریف متغیر و ... استفاده کنیم.

نگران تشابه با زبان های دیگه هم نباش، این قدر ایده هست که اصلا طرف یادش نمی آد این شبیه کدوم زبانه!

با Block ها مخالف نیستم، دوست دارم برای راحتی در یک خط بلاک رو شروع به تعریف کنه و در یک خط پایان بده تعریفو. شبیه BASIC.

----------


## amin32

این چطوره؟


 <main:
a:=c+j
k:=f-t
>

<sampleFunction:
m:=6+4
>

----------


## IamOverlord

سلام دوست عزیز، ببخشید یه مدت نتونستم بیام. 
در مورد sampleFunction اگه می شه یه توضیحی بدید. مثلا آرگومان های ارسالی، تعیین نوع خروجی، ... .
قسمت main و Function شبیه هم نوشته می شن، خوبه یک پارچه تر می شه.
اما تفاوت این دو و ویژگی هاشون چه طور مشخص می شه؟

----------


## IamOverlord

این Syntax رو ببین، ویرایش کن، دوباره بذار:

----------


## amin32

> این Syntax رو ببین، ویرایش کن، دوباره بذار:


این ساختار خوب بود . اما فکر میکنم به دلیل اهمیت ساختار زبان بهتر باشه مرحله به مرحله پیش بریم. یعنی هر دفعه روی یک ساختار (تعریف توابع , حلقه , تعریف متغییر و ...) تمرکز کنیم و وقتی در مورد اون ساختار به توافق رسیدیم , به ساختار بعدی بپردازیم.

به خاطر اهمیت ساختار توابع و مخصوصآ تابع اصلی برنامه بهتره با اون شروع کنیم.



Function Multiply(x : Integer, y : Integer) : Integer
   Multiply = x * y
End Function
 

من با این ساختار تا حدودی موافقم ولی به نظرتون یکم شبیه پاسکال ( پارامترهای ورودی) و vb ( عبارت end function) نشده؟ اگه یکم تغییرش بدیم بهتر میشه.
در ضمن برای تابع اصلی برنامه هم میتونیم از همین ساختار استفاده کنیم.

----------


## IamOverlord

بله ولی سعی کردم هم راحت نوشته بشه، هم راحت خونده بشه، و ...
ضمنا می شه پیچیده تر و بهترش کرد؛ طی این مراحل خود به خود زبانمون بی شباهت به زبان خاضی می شه.
اول در مورد تعریف متغیر بگید، اون : ها رو برای آرگومان های تابع واسه این گذاشتم که فرض کردم تعریف متغیر این طوری هست:
i : Integer
text1 : String
v : Vector

----------


## IamOverlord

ببین 2 راه برای روال اصلی هست:
1. نوشته نشه. یعنی به محض این که کد رو می نویسی در روال اصلی فرض می شه.
2. نوشته بشه. که باید به صورت زیربرنامه در زبانمون تعریف بشه.

مزیت روش 1 سادگی هست.
مزیت روش 2 تمیزی کد و استفاده از آرگومان های ورودی به تابع اصلی در برنامه هست.

البته برای استفاده از آرگومان های ورودی در روش 1، راه هست : بیایم یه دستور برای این کار در نظر بگیریم که در میان کد های روال اصلی، بیاد مقدار ورودی به روال رو از پشته دریافت کنه، یا هر نوع دستور دیگه ای...

----------------------------

اگر روش 2 رو انتخاب کردیم:
روال اصلی، SUB در نظر گرفته بشه یا FUNCTION یا اصلا مثل زبان C تعریف بشه یا ...؟

----------


## amin32

> اول در مورد تعریف متغیر بگید، اون : ها رو برای آرگومان های تابع واسه این گذاشتم که فرض کردم تعریف متغیر این طوری هست:
> i : Integer
> text1 : String
> v : Vector


متوجه منظورتون شدم ولی میگم این نوع آرگومان دهی یکم شبیه پاسکال نشده. اگه به نظرتون این شباهت
ایرادی نداره منم مشکلی ندارم.

----------


## IamOverlord

اگه اشکالی نداره با این ادامه بدیم، دوباره بر می گردیم عقب؟  :متفکر:

----------


## amin32

> اگه اشکالی نداره با این ادامه بدیم، دوباره بر می گردیم عقب؟




موافقم.

پس ساختار توابع شد:


Function Multiply(x : Integer, y : Integer) : Integer
   Multiply = x * y
End Function
 

و تابع اصلی :



Function main() : Integer
   Multiply = x * y
End Function
 

حالا میرسیم به تعریف متغیرها.

----------


## IamOverlord

می گم موافقی انواع متغیر هامون و کنترل نوعمون رو یه مقدارشو از زبان Ada الهام بگیریم؟ یا حتی زبان های دیگه.
زبان C که چیزی نداره!
اما در BASIC یه چیزی هست : String که پیاده سازیشو نمی دونم فعلا. البته پیاده سازی Char و آرایه ای از اون رو مثل زبان C می دونم.

----------


## IamOverlord

مطالعه وبررسي زبانAda از 3 نقطه نظر:
1-      Data : داده هاي Ada  شکل توسعه يافته اي از انواع پاسکال هستند اما قدرت تعريف نوع جديد درآنها بيشتر است .
انواع داده هاي اوليه : شامل صحيح ، حقيقي، کاراکتري،بولي،رشتهايو اشاره گر
انواع ساختمان داده : بردارها ، آرايه ها و فايلها
انواع دادهاي کاربر ساز: رکورد ، زير نوع و ...

2-   عملیات پایه ای (Primitive Operation :/ * mod rem + - abs not &  = /=  ،   >  ،   >=  ،   < ،<= in   -  not in-    And -Or- Xor- And then- Or Else)

3-   Sequence Control: ترتيب انجام عمليات:

- در داخل عبارات جبري:عمليات با تقدم از چپ به راست انجام ميشود . Ada دراي عمليات مدار کوتاه (And then,OR Else) است به طوري که اگر ارزيابي اولين عملوند براي تعيين مقدار عبارت کافي باشد فقط اولين عملوند را ارزيابي ميکند – استثنا پرانتز است
- بين دستورات : ترتيب اجرا بدين ترتيب است که از آدرس پايين تر به آدرس بيشتر اجرا ميشود – استثنا ها – if case loop
-   بين برنامه اصلي و فرعي استثنائ اين مورد پردازش موازي است.

www.atlasshabakeh.com/?m=articles&op=show&id=1315290760

----------


## amin32

فعلا که با پیاده سازی کاری نداریم.فعلا می خوایم ساختار نحوی تعریف متغییر و نام انواع مختلف داده ای رو در زبانمون مشخص کنیم.

bin: برای مقادیر باینری
oct: برای مفادیر مبنای هشت
dec: برای مقادیر دهدهی
hex: مبنای شانزده
integer: اعداد صحیح 
sinteger: اعداد صحیح کوچک
binteger: اعداد صحیح خیلی بزرگ
float: اعداد ممیز شناور
bfloat: اعداد ممیز شناور بزرگ
chr: برای نوع کاراکتری
str: برای نوع رشته


برای تعریف متغیر از ساختار زیر استفاده کنیم:

 variable i:integer

که از کلمه کلیدی variable استفاده میکنه

پیشنهاد من اینه که در اول برنامه یک قسمتی رو در نظر بگیریم که با یک کلمه کلیدی شروع بشه و در اون قسمت متغییرها و انواع جدید و انواع شمارشی و ...(البته اونهایی که قراره به شکل عمومی تعریف بشن) تعریف بشه. مثل:



define:
variable i:integer
variable b:str
end define 
 

نظرت چیه.

----------


## IamOverlord

عالی بود  :تشویق: 
فقط یه پیشنهاد اساسی: برنامه نویس متغیر ها رو در هر جا از برنامه که خواست تعریف کنه (البته در جاهای مجاز :لبخند گشاده!: !) >>> جنبه ی راحتی داره.
حتی بعدا خودمون می تونیم متغیر های تعریف شده رو جمع آوری کنیم و بیاریم اول تعریف کنیم و ...

----------


## amin32

> عالی بود 
> فقط یه پیشنهاد اساسی: برنامه نویس متغیر ها رو در هر جا از برنامه که خواست تعریف کنه (البته در جاهای مجاز!) >>> جنبه ی راحتی داره.


اون که صد در صد . من منظورم متغییرهای سراسری بود.

اما برای کتابخانه ها من یه نظر خوب دارم.هر کتابخانه با پسوند lib ذخیره بشه و به شکل زیر استفاده بشه:

"use "math.lib

----------


## IamOverlord

یه پارامتر جدید می شه برای تعریف متغیر ها در نظر گرفت:
Variable x : Integer(2)
2 ای که داخل پرانتر هست تعداد بایت رو مشخص می کنه، و Integer هم که نوع ذخیره سازی در اون 2 بایت رو.
این طوری زبان انعطاف پذیر تره.
اما یه مسئله ای : آیا قابل پیاده سازی هست؟ مثلا 100 بایت متغیر (!) چه طوری می خواد تو 100 بایت دیگه ریخته بشه؟ در حالت عادی در زبان Assembly این کارو می کنیم:
MOV AX,Variable1
MOV Variable2,AX

که می آد اول Variable1 رو می ریزه تو AX بعد Variable2. ضمنا در این جا چون AX یه ثبات 16 بیتی هست، Variable1 و Variable2 هم همین طور اند. حالا مسئله این جاست ما Register های 100 بایتی نداریم! پس فکر می کنم این ایده ی جدید کارش یه کم وحشتناک باشه، فعلا این ایده رو بذاریم برای بعد...!

----------


## IamOverlord

> اون که صد در صد . من منظورم متغییرهای سراسری بود.
> 
> اما برای کتابخانه ها من یه نظر خوب دارم.هر کتابخانه با پسوند lib ذخیره بشه و به شکل زیر استفاده بشه:
> 
> "use "math.lib


موافقم.
ولی اگه خواستیم بعدا API تعریف کنیم، چی؟
این 2 تا رو با هم بررسی کنیم؟
چون این 2 تا خیلی به هم مربوط هستند.

----------


## IamOverlord

تعریف API باید ارتباط نزدیکی با تعریف توابع ها و زیربرنامه هامون داشته باشه.

----------


## amin32

> پس فکر می کنم این ایده ی جدید کارش یه کم وحشتناک باشه، فعلا این ایده رو بذاریم برای بعد...!


موافقم.راستش وقتی هنوز آخر جملت رو نخونده بودم میخواستم برات بنویسم که یکم پیاده سازیش سخته. که دیگه خودت گفتی  :قهقهه:

----------


## amin32

نمیدونم سرور این سایت فقط برای من اینقدر کند شده یا کلآ اینجوریه. اعصاب برام نذاشت. :عصبانی:

----------


## IamOverlord

سلام دوست عزیز،
ببخشید یه مدت نتونستم بیام.

تو این مدت سورس کد Libry رو خوندم، فهمیدم طرف چه جوری نوشته.
من هم به نظرم از توابعی که نوشته، استفاده کنیم.

این رو دانلود کن:

----------


## amin32

یه مقداری کدش زیاده و حس خوندنش نیست. در ضمن فکر میکنم این توابع بیشتر به درد الگو گرفتن در عقب بندی میخوره. و من میخوام تمام تمرکز روی جلوبندی و تحلیلگرها باشه.

----------


## IamOverlord

خوب در مورد Syntax آخرین تغییرات رو رو این بده:

----------


## IamOverlord

قلب کد اون Libry Compiler، یه روال هست به نام CodeBlock که نکته ی جالبی که در کدش دیدم این بود که اول آخرین فاز کامپایلر رو فراخوانی می کرد، بعد آخرین فاز یه گذری به فاز های قبلی می زد و فاز های قبلی هم همین طور، نه این که بیاد از فاز اول تا آخر رو جدا و پشت سر هم اجرا کنه.

----------


## amin32

دوست عزیز , آسیاب به نوبت.آخه ساختار نحوی یه زبان جدید چیزی نیست که بشه تمامش رو یکجا مشخص کرد. من فکر میکنم همون روند که داشتیم طی میکردیم خوب بود.
یعنی تک تک , ساختارها رو مشخص کنیم و در آخر هم جمعبندی کنیم.




> قلب کد اون Libry Compiler، یه روال هست به نام CodeBlock که نکته ی جالبی که در کدش دیدم این بود که اول آخرین فاز کامپایلر رو فراخوانی می کرد، بعد آخرین فاز یه گذری به فاز های قبلی می زد و فاز های قبلی هم همین طور، نه این که بیاد از فاز اول تا آخر رو جدا و پشت سر هم اجرا کنه.


اما در این مورد باید عرض کنم که تمام کامپایلرها به نوعی به این شکل عمل میکنند. یعنی مثلا تحلیلگر نحوی که در مرحله دوم قرار داره زودتر اجرا میشه و تحلیلگر لغوی که در مرحله اول قرار داره رو فراخوانی کرده و ازش درخواست لغت جدید میکنه. این طبیعیه و ربطی به ترتیب و جداسازی مراحل نداره.

من ساختارهایی که روش تا اینجا اتفاق نظر داشتیم رو جمع آوری میکنم و قرار میدم تا ساختارهای دیگه رو هم به ترتیب بهش اضافه کنیم.

----------


## IamOverlord

> اما در این مورد باید عرض کنم که تمام کامپایلرها به نوعی به این شکل عمل میکنند. یعنی مثلا تحلیلگر نحوی که در مرحله دوم قرار داره زودتر اجرا میشه و تحلیلگر لغوی که در مرحله اول قرار داره رو فراخوانی کرده و ازش درخواست لغت جدید میکنه. این طبیعیه و ربطی به ترتیب و جداسازی مراحل نداره.


خوب راستش من اینو تازه فهمیدم! تصوری در این رابطه نداشتم...




> دوست عزیز , آسیاب به نوبت.آخه ساختار نحوی یه زبان جدید چیزی نیست که بشه تمامش رو یکجا مشخص کرد. من فکر میکنم همون روند که داشتیم طی میکردیم خوب بود.
> یعنی تک تک , ساختارها رو مشخص کنیم و در آخر هم جمعبندی کنیم.


عیب نداره می تونیم همون روند رو طی کنیم... الان در مورد اعلان متغیر ها و این جور مسائل باید صحبت کنیم دیگه؟

----------


## amin32

اینم از ساختارهایی که قبلا در موردش بحث شد و تقریبآ به یک توافقی رسیدیم. البته اگه ایرادی میبینید
لطفآ بیان کنید.


Algorium.rtf.zip

با توجه به این که برنامه های کامپایل شده مبتنی بر کنسول هستند, فکر میکنم اولویت با دستورات ورودی خروجی زبان
یعنی ساختار دستوری خواندن و نوشتن از کنسول باشه.پس بهتره اول اونو مشخص کنیم.

----------


## IamOverlord

خوب به نظرم بهتره دستورات ورودی و خروجی Console جزو دستورات پیش فرض زبان نباشند. یعنی درون ساخت نباشند. بلکه در کتاب خانه ای تعریف شوند از دستورات پایه ای تر.
دستورات پایه ای تر همون دستورات Assembly باشند، یعنی طرف به صورت Inline کد Assembly بنویسه.
پس به نظرم قبلش در این مورد صحبت کنیم که چه طور کد های Assembly اش رو بنویسه.

----------


## IamOverlord

دستت درد نکنه دوست عزیز، تقریبا موافقم:

define:
	variable a:bin
	variable b:oct
	variable c:dec
	variable d:hex
	variable e:integer
	variable f:sinteger
	variable g:binteger
	variable h:float
	variable i:bfloat
	variable j:char
	variable k:str
end define 


1. به نظرم بهتر باشه متغیر ها هر جا که طرف خواست به طور پراکنده تعریف بشن. موافقی؟
2. در مورد مختصر نویسی :
مثل پاسکال از var استفاده بشه به جای variable، یا این که اگر هم مختصر نویسی نمی کنیم نوع متغیر ها رو هم مختصر نویسی نکنیم. مثلا این طوری:

	variable a : binary
	variable b : octal
	variable c : decimal
	variable d : hexadecimal
	variable e : integer
	variable f : sinteger
	variable g : binteger
	variable h : float
	variable i : bfloat
	variable j : character
	variable k : string


3. ضمنا روش ذخیره سازی اعداد hexadecimal، decimal یا ... که با هم فرقی نداره. پس بهت نیست اینا همشون یه نوع باشن، اما کاربر موقع مقدار دهی متغیر ها به شکل دلخواه مقدار دهی کنه؟ ضمنا برای نمایششون هم در مبناهای مختلف می شه توابع و زیربرنامه هایی در نظر گرفت.
یعنی مثلا طرف بنویسه :

variable e : integer

و موقع مقداردهی بتونه از هر کدوم اینا که دلش خواست استفاده کنه:

i = 344
i = 123456789ABCDEFh
i = 0x11011001

یا حالا هر جور دیگه ای که به نظرت می آد...

----------


## amin32

با استفاده از دستورات اسمبلی موافقم. ولی در نهایت که باید یک دستور ساده برای ورودی خروجی داشته باشیم.چه به شکل مستقیم یا به شکل کتابخانه ای.

پیشنهاد من برای دستورات inline :


instraction:
mov ax,bx
sti
mov ss,ax
end instruction

----------


## IamOverlord

برای کار با Console فکر می کنم این توابع API کافی باشه:

Private Declare Function AllocConsole Lib "kernel32" () As Long
Private Declare Function FreeConsole Lib "kernel32" () As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function GetStdHandle Lib "kernel32" (ByVal nStdHandle As Long) As Long
Private Declare Function WriteConsole Lib "kernel32" Alias "WriteConsoleA" (ByVal hConsoleOutput As Long, lpBuffer As Any, ByVal nNumberOfCharsToWrite As Long, lpNumberOfCharsWritten As Long, lpReserved As Any) As Long
Private Declare Function ReadConsole Lib "kernel32" Alias "ReadConsoleA" (ByVal hConsoleInput As Long, ByVal lpBuffer As String, ByVal nNumberOfCharsToRead As Long, lpNumberOfCharsRead As Long, lpReserved As Any) As Long
Private Declare Function SetConsoleTextAttribute Lib "kernel32" (ByVal hConsoleOutput As Long, ByVal wAttributes As Long) As Long
Private Declare Function SetConsoleTitle Lib "kernel32" Alias "SetConsoleTitleA" (ByVal lpConsoleTitle As String) As Long
Private Declare Function GetConsoleTitle Lib "kernel32" Alias "GetConsoleTitleA" (ByVal lpConsoleTitle As String, ByVal nSize As Long) As Long
Private Declare Function GetConsoleWindow Lib "kernel32" () As Long
Private Declare Function GetConsoleCursorInfo Lib "kernel32" (ByVal hConsoleOutput As Long, lpConsoleCursorInfo As CONSOLE_CURSOR_INFO) As Long
Private Declare Function SetConsoleCursorInfo Lib "kernel32" (ByVal hConsoleOutput As Long, lpConsoleCursorInfo As CONSOLE_CURSOR_INFO) As Long
Private Declare Function GetConsoleMode Lib "kernel32" (ByVal hConsoleHandle As Long, lpMode As Long) As Long
Private Declare Function SetConsoleMode Lib "kernel32" (ByVal hConsoleHandle As Long, ByVal dwMode As Long) As Long
Private Declare Function WriteConsoleOutputCharacter Lib "kernel32" Alias "WriteConsoleOutputCharacterA" (ByVal hConsoleOutput As Long, ByVal lpCharacter As String, ByVal nLength As Long, ByVal dwWriteCoord As Long, lpNumberOfCharsWritten As Long) As Long
Private Declare Function GetConsoleScreenBufferInfo Lib "kernel32" (ByVal hConsoleOutput As Long, lpConsoleScreenBufferInfo As CONSOLE_SCREEN_BUFFER_INFO) As Long
Private Declare Function SetConsoleCursorPosition Lib "kernel32" (ByVal hConsoleOutput As Long, ByVal dwCursorPosition As Long) As Long
Private Declare Function FillConsoleOutputCharacter Lib "kernel32" Alias "FillConsoleOutputCharacterA" (ByVal hConsoleOutput As Long, ByVal cCharacter As Byte, ByVal nLength As Long, dwWriteCoord As Long, lpNumberOfCharsWritten As Long) As Long
Private Declare Function SetConsoleCtrlHandler Lib "kernel32" (ByVal HandlerRoutine As Long, ByVal Add As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDest As Any, pSrc As Any, ByVal ByteLen As Long)
Private Declare Function GetVersionEx Lib "kernel32" Alias "GetVersionExA" (lpVersionInformation As OSVERSIONINFO) As Long


نمونه ی کارشون اینه:

----------


## IamOverlord

> با استفاده از دستورات اسمبلی موافقم. ولی در نهایت که باید یک دستور ساده برای ورودی خروجی داشته باشیم.چه به شکل مستقیم یا به شکل کتابخانه ای.
> 
> پیشنهاد من برای دستورات inline :
> 
> 
> instraction:
> mov ax,bx
> sti
> mov ss,ax
> end instruction


یه فکری می گم بیایم شبیه Pure BASIC دستورات Assembly رو بدون تعریف Block و سه سوته قابل استفاده کنیم؟ یعنی کاملا مستقیم و بدون استفاده از Instruction.

در مورد دستورات ورودی و خروجی هم 2 حالت داره:
1. می تونه توابع API که گفتم رو تعریف کنه و یا از کتابخانه هایی که این توابع توشون تعریف شده استفاده کنه.
2. اگه توانایی استفاده از Interrupt ها رو توسط دستورات Assembly داره، می تونه این کارو بکنه یا از کتاب خانه هایی که از قبل از این دستورات در زیربرنامه ها و توابعشون استفاده کردن، استفاده کنه.

----------


## amin32

> 1. به نظرم بهتر باشه متغیر ها هر جا که طرف خواست به طور پراکنده تعریف بشن. موافقی؟


قبلا گفتم که کاربر میتونه در هر تابعی متغیر تعریف کنه و این ساختار define که در ابتدای برنامه هست فقط برای تعریف متغیرها و ساختارهایی هست که به شکل سراسری به کار برده میشن.




> 2. در مورد مختصر نویسی :
> مثل پاسکال از var استفاده بشه به جای variable، یا این که اگر هم مختصر نویسی نمی کنیم نوع متغیر ها رو هم مختصر نویسی نکنیم.


خودم هم var رو بهتر میدونم ولی همونطور که گفتید خیلی شبیه پاسکال میشد. درمورد کامل نوشتن انواع هم ربطی نمی بینم و فقط اوضاع رو بدتر میکنه.
به غیر از var و variable کلمه دیگه ای به ذهنتون نمیرسه که هم کوتاه باشه هم مناسب؟ :متفکر: 

درباره مورد سوم هم باید بگم که میتونیم فعلا از این انواع صرف نظر کنیم و اونا رو یک نوع در نظر بگیریم تا شاید بعدآ بهشون فکر کنیم.

----------


## IamOverlord

مثلا فرض کن توانایی استفاده از توابع API رو داره؛ می تونه یه Library تعریف کنه و مثلا اینا رو توش بنویسه:

Import Function "WriteConsoleA" From "KERNEL32.DLL" As WriteConsole (ByVal hConsoleOutput : Long, lpBuffer : Any, ByVal nNumberOfCharsToWrite : Long, lpNumberOfCharsWritten : Long, lpReserved : Any) : Boolean

Function WriteString(sWhat : String) : Long
     WriteConsole hConsoleOut, ...
End Function

----------


## IamOverlord

شاید بخواد یه سری از متغیر ها Global تعریف بشن و از بیرون هم قابل دسترسی باشن، یا یه سری Private تعریف بشن و فقط از داخل (نه داخل یه روال خاص، داخل همه ی روال ها) قابل فراخوانی باشن. نظر شما چیه که این کارو کنیم:
Public MainProgramTitle : String = "First Project"
Private WebsiteAddress : String = "www.barnamenevis.org"

Function Main() : Integer

End Function

این ساختار تعاریف رو بررسی کنید:
' Variable Declaration:
MainProgramTitle : String = "First Project"
Private WebsiteAddress : String = "www.barnamenevis.org"
' Object Declaration:
Object Apple : Fruit
Public Object Orange : Fruit
' Win API Declaration
Import Function “DeleteDC” From “GDI32.DLL” As DelDC (ByVal hdc : Long) : Long


هم کوتاهه هم همه چیو می تونه مشخص کنه.

----------


## amin32

راستش یه خورده از حرفات در مورد api گیج شدم ولی فقط اینو بگم که اگه منظورت متکی بودن به api ویندوزه باید بگم اصلا کار منطقی ای نیست.
ببین مثلا زبان سی رو در نظر بگیر. به نظر من یکی از کاملترین کامپایلرهای این زبان gcc هست که اصولا برای لینوکس توسعه داده شده.
یکی از راههای متداول کار با ورودی خروجی به این شکل هست که ما اول میایم یه فایل سرایند <stdio.h> رو در برنامه معرفی میکنیم و
در برنامه میتونیم از دستورات printf و scanf برای ورودی خروجی استفاده کنیم . نظر من اینه که استفاده کلی از چنین ساختاری منطقی تر به نظر میرسه.

----------


## IamOverlord

نه ما متکی به API ویندوز نیستیم، یا به Interrupt خاص یا هر چیز دیگه ای.
هر سیستمی API ها و Interrupt های خاص خودشو داره. ما یه تابع می نویسیم برای سیستم های مختلف که اگه Windows بود از فلان چیز استفاده کنه، اگه Linux بود از یه چیز دیگه... .
یعنی این که نهایتا از چه چیزی استفاده شه به عهده ی کامپایلر هست بر اساس درخواست کاربر.
حتی زبان ++C هم همین کارو می کنه.
یعنی تو یه کد می نویسی و از توابع یکسانی استفاده می کنی، در صورتی که خروجی ها بر اساس کامپایلر ها در محیط های مختلف متفاوت هست.
اگه می خوایم مثل ++C کار کنیم، پس باید یه روشی بذاریم که برنامه نویس اون روال، به کامپایلر بگه اگه برای این سیستم کامپایل می کنی این کد رو بزن، برای اون سیستم اون یکی کد رو بزن... مثل # در ++C که فقط با کامپایلر صحبت می کنه. مثلا فرض کن این طوری:

#if system = DOS
{
   ...
   int 21h
}
elseif system = Windows
{
   ...
   WriteConsole ...
}
else
{
   ...
}

که این if ها در زمان اجرا، اجرا نمی شن و در زمان Compile پردازششون به عهده ی Pre-Processor هست.

----------


## amin32

ببین من فکر میکنم که فعلآ نباید بحث استفاده از توابع API مربوط به OS رو به میان میاوردی. ما باید یک ساختاری درست کنیم که برنامه نویس بتونه
با ورودی خروجی (که شامل فایل هم میشه) کار کنه و لزومی نداره که کاربر در برنامه از توابع os استفاده کنه. به نظر من بهترین کار اینه که ما 
 مثل سی تعریف توابع یا حتی فقط مشخصات توابع ورودی خروجی رو در یک فایل سرایند یا کتابخانه ذخیره کنیم و کاربر بتونه با به کار بردن این فایل 
از توابع ورودی خروجی استفاده کنه و این که در نهایت اجرای دستورات ورودی خروجی به چه شکل باشه بستگی به کامپایلر ما و کد ماشینی که در عقب بندی تولید میشه داره 
و لزومی نداره کاربر از اون مطلع باشه.

----------


## amin32

در ضمن به نظر من بهتر بود اول یه زبان پایه رو با دستورات اصلی بنا میزاشتیم و اگر تونستیم اون رو به اتمام برسونیم
یعنی تحلیلگر نحوی و معنایی و دیگر مراحل کامپایلر رو که میتونه خیلی دشوار باشه رو پیاده کنیم, اونوقت میتونستیم به فکر
توسعه زبان باشیم (تعریف نوع , استفاده از API , سرایند, کتابخانه,شی گرایی , برنامه نویسی گرافیکی ووووو......). چون اکثر زبانها هم یک چنین مسیری رو طی کردند.

----------


## IamOverlord

> ببین من فکر میکنم که فعلآ نباید بحث استفاده از توابع API مربوط به OS رو به میان میاوردی. ما باید یک ساختاری درست کنیم که برنامه نویس بتونه
> با ورودی خروجی (که شامل فایل هم میشه) کار کنه و لزومی نداره که کاربر در برنامه از توابع os استفاده کنه. به نظر من بهترین کار اینه که ما 
>  مثل سی تعریف توابع یا حتی فقط مشخصات توابع ورودی خروجی رو در یک فایل سرایند یا کتابخانه ذخیره کنیم و کاربر بتونه با به کار بردن این فایل 
> از توابع ورودی خروجی استفاده کنه و این که در نهایت اجرای دستورات ورودی خروجی به چه شکل باشه بستگی به کامپایلر ما و کد ماشینی که در عقب بندی تولید میشه داره 
> و لزومی نداره کاربر از اون مطلع باشه.


خوب شما فرض کن ما بحث توابع و ...، رو از برنامه نویس بپوشونیم. حالا قراره این چیزا رو داخل یه فایل سرآیند قرار بدیم. اون فایل هم توابع و روال هایی داره که با زبان برنامه نویسی خودمون ساخته شدن. اون ها باید با چی ساخته می شدن؟ یعنی پایه ای ترین دستورات برای ساخت دستورات سطح بالاتر (کار با فایل و ورودی و خروجی متن و ...) چیان؟ مسلما دستورات Assembly هستن. زبان C رو هم اگه بدون فایل های سرآیندش در نظر بگیری، باز هم قابل استفادس، چون خود فایل های سرآیندش در نهایت با دستورات پایه ای تری نوشته شدن، که شما می تونی اونا رو داخل برنامه ی خودتم بنویسی. منم می گم این کارو کنیم. یعنی در ابتدا هیچ دستور خاصی برای زبان قرار ندیم (برعکس BASIC)، بلکه این قابلیت رو به برنامه نویس (کسی که فایل های سرآیند رو می نویسه یا هر کس دیگه ای) بدیم که این دستورات (نوشتن و خواندن و ...) رو بنویسه، با دستورات پایه ای تر زبان (مثل زبان C).

----------


## amin32

به نظر من ملزومات یک زبان برنامه نویسی تحت کنسول اینها هستند:

۱- ساختار تعریف متغیر
۲- ساختار تعریف توابع
۳- ساختار نحوی عملگرها و دستورات محاسباتی
۴- ساختارهای شرطی
۵- ساختار حلقه و تکرار


و البته دستورات ورودی خروجی

----------


## IamOverlord

> در ضمن به نظر من بهتر بود اول یه زبان پایه رو با دستورات اصلی بنا میزاشتیم و اگر تونستیم اون رو به اتمام برسونیم
> یعنی تحلیلگر نحوی و معنایی و دیگر مراحل کامپایلر رو که میتونه خیلی دشوار باشه رو پیاده کنیم, اونوقت میتونستیم به فکر
> توسعه زبان باشیم (تعریف نوع , استفاده از API , سرایند, کتابخانه,شی گرایی , برنامه نویسی گرافیکی ووووو......). چون اکثر زبانها هم یک چنین مسیری رو طی کردند.


قبول دارم که زبان ها اول اصلشون ساخته شده بعد توسعه پیدا کردن و مثلا فایل های سرآیند براشون نوشته شده. ولی این ساده تره که ما هیچ دستوری رو ننویسیم به طور پیش فرض، بلکه کاربر (مثلا موقع توسعه) خودش بیاد اون دستورات جورواجور رو تولید کنه. فقط کافیه مثل زبان C اجازه بدیم که کد Assembly بزنه.

----------


## IamOverlord

> و البته دستورات ورودی خروجی


به جای این گزینه می شد گفت دستورات پایه.
با دستورات پایه ای Assembly می شه دستورات ورودی و خروجی رو پیاده سازی کرد.
دیگه این بستگی به سلیقه ی ما داره که دستورات پایه ای مون چیا باشن...

----------


## amin32

> قبول دارم که زبان ها اول اصلشون ساخته شده بعد توسعه پیدا کردن و مثلا فایل های سرآیند براشون نوشته شده. ولی این ساده تره که ما هیچ دستوری رو ننویسیم به طور پیش فرض، بلکه کاربر (مثلا موقع توسعه) خودش بیاد اون دستورات جورواجور رو تولید کنه. فقط کافیه مثل زبان C اجازه بدیم که کد Assembly بزنه.


من که هر چقدر توی فایلهای سرایند پر استفاده زبان سی گشتم دستور اسمبلی ندیدم و بیشتر تعریف مشخصات توابع. البته مطمعن نیستم.
ولی فکر میکنم بیشتر دستورات اسمبلی در مواقعی به کار میاد که نشه از دستورات زبان استفاده کرد. مثل وقتی که بحث ساخت کرنل به میان میاد. باید بیشتر تحقیق کرد.
وای برم که بازی تیمم شروع شد. انشاالله که این دفعه رو میبریم.... :تشویق:

----------


## IamOverlord

در پوشه ی Include خوب بگردی پیدا می کنی.
البته چون اکثرشون به هم دیگه پاس می دن (کدوم تیم؟  :لبخند گشاده!: ) کم تر دستورات Assembly می بینی. ولی برای نمونه، آخر این header file رو نگاه کن:

// --aclcls.h------------------------------------------------------------------
//
// Interface to library: aclcls.
//
// Copyright 1986 - 1998 Microsoft Corporation. All rights reserved.
//
// ----------------------------------------------------------------------------

#if !defined(_ACLCLS_H_)
#define _ACLCLS_H_


// $$--IExchangeFolderACLs-----------------------------------------------------
//
// Definition of interface for folder ACLs class CFolderACLs.
//
// ----------------------------------------------------------------------------

#undef		 INTERFACE
#define		 INTERFACE  IExchangeFolderACLs

// Manifest for cursor position indicating we are at the end of the ACLs table.

#define	ACL_PAST_END		((LONG) -1)


// Special ACL positions.  The special ACL's at these position may not be
// deleted, and there are also special rules (coming from Exchange) with
// regard to how rights will be modified.  Also, other ACL's may not be inserted
// at these positions.

#define	ACL_POS_DEFAULT		((LONG) 0)
#define	ACL_POS_CREATOR		((LONG) 1)

DECLARE_INTERFACE_(IExchangeFolderACLs, IUnknown)
{
#ifndef NO_BASEINTERFACE_FUNCS

    /* IUnknown methods */

	STDMETHOD(QueryInterface)(
		THIS_
		REFIID					riid,
		LPVOID FAR *			ppvObj
		)										PURE;

    STDMETHOD_(ULONG, AddRef)(
		THIS
		)										PURE;

    STDMETHOD_(ULONG, Release)(
		THIS
		)										PURE;

#endif

    /* IExchangeFolderACLs methods */

    STDMETHOD(HrDelete)(
		THIS
		)													PURE;

    STDMETHOD(HrGet)(
		THIS_
		LPLONG					lplRights,
		LPSTR FAR *				lppszDisplayName,
		ULONG FAR *				lpcbentryid,
		LPENTRYID FAR *			lppentryid
		)													PURE;

    STDMETHOD(HrInsert)(
		THIS_
		LONG					lRights,
		LPSTR					lpszDisplayName,
		ULONG					cbentryid,
		LPENTRYID				lpentryid,
		LPLONG					lplRights
		)													PURE;

    STDMETHOD(HrModify)(
		THIS_
		LONG					lRights,
		LPLONG					lplRights
		)													PURE;

    STDMETHOD(HrSeek)(
		THIS_
		LONG					lPos
		)													PURE;

    STDMETHOD(HrTell)(
		THIS_
		LPLONG					lplPos
		)													PURE;
};

// $$--LPFOLDERACLS------------------------------------------------------------
//
// Pointer to IExchangeFolderACLs interface.
//
// ----------------------------------------------------------------------------

typedef IExchangeFolderACLs FAR * LPFOLDERACLS;

//
// Helper functions defined in module ACLCLS.
//

// $--HrFolderACLsOpen---------------------------------------------------------
//
// DESCRIPTION:	Get a pointer to an object which implements the
//				IExchangeFolderACLs interface defined in aclcls.h.
//
// INPUT:
//
//  [lpSession]         -- Pointer to MAPI session.
//	[lpMDB]				-- Pointer to message store containing folder.
//  [cbentryid]			-- Number of bytes in folder's entry identifier.
//  [lpentryid]			-- Folder's entry identifier.
//
// OUTPUT:
//
//  [lppFolderACLs]		-- Pointer to object which supports interface.
//						   NULL if none.
//
// RETURNS:     NOERROR			if successful;
//				E_INVALIDARG	if bad input;
//				E_OUTOFMEMORY	if not enough memory;
//				E_NOINTERFACE	if acl table does not exist on folder;
//              E_FAIL 			otherwise.
//
//-----------------------------------------------------------------------------

STDAPI
HrFolderACLsOpen(								// RETURNS: HRESULT
    IN      LPMAPISESSION       lpSession,      // MAPI session pointer
	IN		LPMDB				lpMDB,			// MAPI MDB store ptr
	IN		ULONG				cbentryid,		// # bytes in entry ID
	IN		LPENTRYID			lpentryid,		// entry ID ptr
	OUT		LPFOLDERACLS FAR *	lppFolderACLs	// IExchangeFolderACLs ptr ptr
	);

#endif

----------


## IamOverlord

> ۱- ساختار تعریف متغیر
> ۲- ساختار تعریف توابع
> ۳- ساختار نحوی عملگرها و دستورات محاسباتی
> ۴- ساختارهای شرطی
> ۵- ساختار حلقه و تکرار


1 و 2 رو تا یه حدودایی مشخص کردیم.
در مورد 3،
مثلا اینو ببین:
f : Boolean
a : Integer = 13
b : Integer = 33
f = (a = b)?      ' = true
f = Not (a > b)?  ' = not false =true
f = (a < b and b = a)?   ' = false

----------


## amin32

فکر کنم دیگه باختیم... :گریه:  :گریه:  :گریه: 




> 1 و 2 رو تا یه حدودایی مشخص کردیم.
> در مورد 3،
> مثلا اینو ببین:
> f : Boolean
> a : Integer = 13
> b : Integer = 33
> f = (a = b)?      ' = true
> f = Not (a > b)?  ' = not false =true
> f = (a < b and b = a)?   ' = false


خب در مورد عملگرها و دستورات هم قبلآ تا حدودی صحبت شد.
اما در مورد دستورات شرطی نظرم اینه:


if (i>10):
i=i+1
end if

----------


## IamOverlord

بیش تر Symbol ها هستن که تو ++C دست و پا گیرن، به نظرم ساختار if زبان BASIC یکی از بهترین ساختار ها هست. (ببخشید این قدر مخالفت می کنما ولی... دیگه دیگه...)

' Simple If Structure
If _Statement_ Then Beep()

' Complete If Structure
If Statement1 Then

ElseIf Statement2 Then

ElseIf Statement3 Then

Else 

End If

حالا می تونیم اینو کامل ترش کنیم البته اگه بشه.

----------


## IamOverlord

نه پشیمون شدم! به خاطر یکپارچگی با ?(...) ، بهتره از If (...) Then استفاده کنیم نه If ... Then.





> فکر کنم دیگه باختیم...



من فکر کردم پروژه رو می گی...!  :لبخند گشاده!:

----------


## amin32

> بیش تر Symbol ها هستن که تو ++C دست و پا گیرن، به نظرم ساختار if زبان BASIC یکی از بهترین ساختار ها هست. (ببخشید این قدر مخالفت می کنما ولی... دیگه دیگه...)
> 
> ' Simple If Structure
> If _Statement_ Then Beep()
> 
> ' Complete If Structure
> If Statement1 Then
> 
> ElseIf Statement2 Then
> ...


این یکم زیادی شبیه خود بیسیک نشده؟ اگه دقت کنی پیشنهاد منم تقریبآ همین بود با این تفاوت که بجای then از ':' استفاده کنیم.

----------


## IamOverlord

من تا جایی که دیدم زبان های دیگه ای هم هستن که ساختارشون مثل اینه (این قدر ساختار توپیه!)؛
مثلا این جا رو حتما ببین برای Ada هست.
این جا هم برای Fortran هست.
تازه، می ریم جلو زبان ساخته می شه انشاا... ، بعد بر می گردیم دوباره یه تغییرات جزئی روی Syntax می دیم و اگه ایده ی جدید و بهتری داشتیم پیاده می کنیم.

----------


## amin32

> من تا جایی که دیدم زبان های دیگه ای هم هستن که ساختارشون مثل اینه (این قدر ساختار توپیه!)؛
> مثلا این جا رو حتما ببین برای Ada هست.
> این جا هم برای Fortran هست.
> تازه، می ریم جلو زبان ساخته می شه انشاا... ، بعد بر می گردیم دوباره یه تغییرات جزئی روی Syntax می دیم و اگه ایده ی جدید و بهتری داشتیم پیاده می کنیم.



من فقط نظرم این بود که به جای then از یه لغت یا علامت دیگه استفاده بشه. ولی اشکالی نداره اگه اینطوری می خوای با همین پیش میریم.

----------


## IamOverlord

ساختار های غیر از if چی؟
اگه بشه یه جوری همشون رو یکپارچه و منظم کرد خیلی خوب می شه...  :متفکر:

----------


## amin32

به خودم امیدوار شدم.فکر میکردم فقط من اینقدر بیخوابم. :قهقهه: 

خب تا منظورت از یکپارچگی چی باشه؟

----------


## IamOverlord

ساختار Select Case چه طور باشه؟  :متفکر: 

' halqeye bi nahayat:
Do

Loop

' sakhtare while
While (...) Do

Loop


' sakhtare until
Until (...) Do

Loop

' sakhtare for e sade
For i : 1 To 10 Do

Loop

' sakhtare for ba step
For i : 10 To 1 Step -1 Do

Loop

' sakhtare select
Select ...
Case ...

Case ...

Case Else

End Select

----------


## IamOverlord

منظورم از یکپارچگی همون ساختار Do Loop پست بالا هست. اگه دقت کنی ساختار های For، While و Until کامل شده ی Do Loop هستند.
یه سوالی: می تونیم در زبانمون یه مفهومی به نام مجموعه تعریف کنیم و For رو به اون ربط بدیم؟ (برای یکپارچگی بیشتر!  :لبخند گشاده!:  :قهقهه: )

----------


## amin32

> منظورم از یکپارچگی همون ساختار Do Loop پست بالا هست. اگه دقت کنی ساختار های For، While و Until کامل شده ی Do Loop هستند.



خوب اگه منظورت این باشه , باید بگم که این به فکر بیشتری نیاز داره. :متفکر:

----------


## IamOverlord

آها، یه مسئله ای:
بیرون اومدن از ساختار های For، While و ... ؟  :لبخند گشاده!: 
(یکپارچه!)

----------


## amin32

اگه منظورت از بیرون اومدن دستوری مثل exit for هست , من میگم که یکپارچه باشه

----------


## IamOverlord

باشه. ضمنا یه مزیتی که ++C داره این هست که می شه در ساختار Switch اش تعیین کرد که همه ی Case ها رو بررسی کنه یا این که از فلان Case به بعد در صورت برقراری دیگه بررسی نکنه. می خوام این قابلیت رو ما هم بذاریم. در کل می خوام یه سری از ویژگی های خوب زبان ++C رو بذاریم.

----------


## amin32

> باشه. ضمنا یه مزیتی که ++C داره این هست که می شه در ساختار Switch اش تعیین کرد که همه ی Case ها رو بررسی کنه یا این که از فلان Case به بعد در صورت برقراری دیگه بررسی نکنه. می خوام این قابلیت رو ما هم بذاریم. در کل می خوام یه سری از ویژگی های خوب زبان ++C رو بذاریم.


همون قضیه دستور break دیگه. آره فکر خوبیه.

صبح شد  :قهقهه:

----------


## amin32

فقط یه نکته ای. چون من دانشجو هستم فقط تا همین یک ماه آینده وقت آزاد دارم و بعد اون
با عرض شرمندگی وقتم محدودتر میشه. اینو گفتم که در جریان باشید تا یکم زودتر به پیاده سازی بپردازیم.

----------


## IamOverlord

:قهقهه: 
پس Break روی اینا تاثیر بذاره:
- ساختار Select
- ساختار Do Loop کلا، که شامل For، While و ... می شه.

اما مثالی از روش کار:

Break 3

که می گه 3 بار Break کن پشت سر هم.
به جای 3 اگه عدد ثابت بذاره که مشکلی نیست ولی اگه متغیر بذاره  :ناراحت: . پس متغیر نذاره. اصلا واسه چی بذاره؟ کاربرد زیادی نداره. زبان های دیگه هم یادم نمی آد که همچین امکانی رو برای متغیر گذاشتن، در نظر گرفته باشن. می تونه از Goto استفاده کنه، یا همون Jump در Assembly. ببین اگه کد Assembly بدون Block و از این حرفا نوشته می شه، دستور Jump به تنهایی به کارش می آد و لازم نیست دوباره Goto رو تعریف کنیم.

----------


## amin32

در مورد اسمبلی یه مشکل بزرگ رو در نظر نگرفتی. اگه زبان ما از اسمبلی به شکل inline استفاده کنه , اونوقت باید ساختار لغوی و نحوی زبان اسمبلی رو هم پیاده سازی کنیم !!!!!!!!
یعنی دو تا زبان که خیلی پیچیده میشه. به این دلیله که میگم این مسائل رو بزاریم برای مرحله توسعه زبان.

----------


## amin32

> پس Break روی اینا تاثیر بذاره:
> - ساختار Select
> - ساختار Do Loop کلا، که شامل For، While و ... می شه.


آره. البته لزومی نداره که از همه این دستورات و با همین ساختار لغوی استفاده بشه و بهتر که دنبال یه ساختار جدیدتر یا با لغاتی متفاوت باشیم (منظورم از لغت مثلا کلمه loop یا کلمات دیگه هست)

----------


## IamOverlord

> در مورد اسمبلی یه مشکل بزرگ رو در نظر نگرفتی. اگه زبان ما از اسمبلی به شکل inline استفاده کنه , اونوقت باید ساختار لغوی و نحوی زبان اسمبلی رو هم پیاده سازی کنیم !!!!!!!!
> یعنی دو تا زبان که خیلی پیچیده میشه. به این دلیله که میگم این مسائل رو بزاریم برای مرحله توسعه زبان.


نه ما دستورات Assembly رو بدون هیچ پردازشی (یا با حداقل پردازش ممکن!) می دیم به Assembler مشکلی نداره... :متفکر:  ضمنا دستورات Assembly تجزیه و تحلیل پیچیده ای برای Compiler ندارن...

----------


## IamOverlord

> 0- دستورات Assembly
> ۱- ساختار تعریف متغیر
> ۲- ساختار تعریف توابع
> ۳- ساختار نحوی عملگرها و دستورات محاسباتی
> ۴- ساختارهای شرطی
> ۵- ساختار حلقه و تکرار


4 و 5 ارتباط نزدیکی با هم دارن، به خاطر همین می گم یکپارچه باشن.
While/Until
Select Case
For
If
و ... ؟



چه قدر تاپیک خلوته، ای کاش بقیه هم مشارکت کنن...!

----------


## IamOverlord

برای Dynamic Allocation هم فهمیدم باید چی کار کنیم!!! می تونی یه جست و جویی در مورد Heap Allocation و ... بکنی. این جا رو ببین.

----------


## amin32

> نه ما دستورات Assembly رو بدون هیچ پردازشی (یا با حداقل پردازش ممکن!) می دیم به Assembler مشکلی نداره... ضمنا دستورات Assembly تجزیه و تحلیل پیچیده ای برای Compiler ندارن...


ببین , وقتی داری به هر ایده فکر میکنی باید به فکر پیاده سازی هم باشی. یکی از کارای مهم کامپایلر تشخیص خطاهای لغوی و نحویه. ok ؟ خوب به نظر تو وقتی تحلیلگر ما به ساختار نحوی یک دستور اسمبلی برخورد کرد باید چه رفتاری داشته باشه.از کجا بفهمه این یه یه دستور اشتباه نیست و دستور اسمبلی هست ؟ خوب یه راه حل اینه که دستورات اسمبلی رو داخل یه جور بلاک خاص قرار بدیم (مثل کامپایلرهای دیگه) و وقتی که تحلیلگر  به این بلاک برخورد کرد اونو مستقیمآ به اسمبلر بفرسته!). اما باز به نظر من این کار منطقی نیست چون فرض کن اگه دستور اسمبلی اشتباه باشه دیگه ما تونایی تشخیص نوع و محل خطا رو نداریم.

----------


## IamOverlord

خوب Assembler و Linker در مرحله ی بعد خطا ها رو گزارش می کنن...
ضمنا Instuction های Assembly ساختار ساده ای دارن، یا عملوند ندارن، یا یه دونه دارن یا دو تا، بدون هیچ ساختار پیچیده یا عجیب و غریب خاصی...

----------


## amin32

> خوب Assembler و Linker در مرحله ی بعد خطا ها رو گزارش می کنن...
> ضمنا Instuction های Assembly ساختار ساده ای دارن، یا عملوند ندارن، یا یه دونه دارن یا دو تا، بدون هیچ ساختار پیچیده یا عجیب و غریب خاصی...


در مورد اولی که گفتی, مجبوریم که اسمبلر رو با کامپایلر یکپارچه کنیم. و در کدش هم دست ببریم.که دردسرهای خاص خودش رو داره.
در مورد دومی هم فقط مساله ساختار نحوی نیست بلکه باید دستورات زبان و انواع ثبات رو بررسی کنه. شاید به نظر اینا ساده بیاد ولی وقتی دارم تصور میکنم که تحلیلگرهایی که براشون کد مینویسم باید از اسمبلی هم حمایت کنند, کارو خیلی سخت میبینم. منطقی باش ما تجربه بورلند رو نداریم!

----------


## IamOverlord

باشه،
اگه می خوای اینو می ذاریم واسه بعد...
برای برنامه های Windows کاربر حتما باید بتونه API تعریف کنه یا بالاخره ما باید براش تعریف کنیم...
چی کار کنیم؟ روش تعریف چی باشه؟

----------


## amin32

> باشه،
> اگه می خوای اینو می ذاریم واسه بعد...
> برای برنامه های Windows کاربر حتما باید بتونه API تعریف کنه یا بالاخره ما باید براش تعریف کنیم...
> چی کار کنیم؟ روش تعریف چی باشه؟



من الان حضور ذهن ندارم. میشه بگی مثلا چه توابعی در برنامه نویسی کنسول میتونه مورد استفاده باشه. خوب توابع مربوط به گرافیک و کنترل ها که اصلا کاربردی نداره. خوب دیگه چی میتونه مورد استفاده برنامه نویس باشه.(از بس دیگه با ویندوز کار نکردم توابعش یادم رفت :قهقهه: )

----------


## IamOverlord

اونایی که تو پست 75 گذاشتم.

----------


## amin32

خوب یه چیزایی یادم اومد
مثلا توابع مربوط به اطلاعات دیسک که راه دیگه ای به غیر از استفاده از Api نیست. با این حساب باید کاربر بتونه از api استفاده کنه.
پس باید یه ساختار براش پیدا کنیم.

----------


## IamOverlord

این روش رو ببین قبول داری:
Import Function “DeleteDC” From “GDI32.DLL” As DelDC (ByVal hdc : Long) : Long

----------


## amin32

> اونایی که تو پست 75 گذاشتم.


نه نه... این توابع مربوط به کار با کنسول هستند. بهتره در این مورد مستقل از پلتفرم عمل کنیم. هیچ زبانی رو سراغ ندارم که برای کارهای ابتدایی مثل نوشتن در خط فرمان متکی به API ویندوز باشه.(البته منظورم زبانهای تحت کنسول هست)

----------


## amin32

> این روش رو ببین قبول داری:
> Import Function “DeleteDC” From “GDI32.DLL” As DelDC (ByVal hdc : Long) : Long


آره خوب.

فقط یه چیزی... ما مجبوریم فقط از dll های اصلی ویندوز حمایت کنیم.و نمیتونیم از dll های دیگه پشتیبانی کنیم.چون به توابع داخلش و آرگومانهاشون أشنا نیستیم . ولی فکر میکنم چند سال پیش یه راه برای اینکار پیدا کرده بودم.باید بررسی کنیم.

----------


## IamOverlord

نگاه کن اگه بخوای مستقل از Platform عمل کنی نمی تونی یه کد رو برای چند Platform کامپایل کنی. باید برای Windows از API استفاده کنی، برای Lunux از وقفه ی 80h استفاده کنی و برای فلانی فلان کارو کنی. حالا اگه نه بتونی از وقفه استفاده کنی، نه حداقل API تعریف کنی، هیچ کار نمی تونی بکنی. بعدشم قرار نیست توابعی که با API ها یا وقفه ها تعریف می شن رو هر دفعه کاربر تعریف کنه. بلکه باید یه بار اینا رو توی فایل های lib تعریف کنیم. حالا اگه بخوایم یه روال بنویسیم برای چند Platform، باید همین کاری که در زبان C یا زبان های دیگه می کنند رو انجام بدیم، یعنی یه سری If تعریف کنیم که اینا اجرا نشن، فقط کامپایلر موقع کامپایل چکشون کنه یا حالا هر کار دیگه ای... مثلا اگه با FASM کار کنی می بینی که یه کتابخانه ای ساختن برای Windows، Linux و DOS که تو یک کد رو می نویسی و برای Platform های مختلف کامپایل می کنی. اما از کجا می فهمه Platform ات چی می خوای باشه، می بینه که System رو (نام یه ثابت هست) برابر با چی قرار دادی تو برنامت.
می بینی که هر زبانی (که مستقل از Platform هست) یه روشی رو برای کامپیال کردن واسه Platform مورد نظر، در نظر گرفته. اما در نهایت باید امکان استفاده از امکانات هر Platform وجود داشته باشه که حالا بخواد انتخابی صورت بگیره.
اگه می خوای مستقل از Platform بنویسیم باید هم بتونه از Interrupt ها استفاده کنه و هم بتونه از API ها استفاده کنه (API ها مختص Windows نیستن هر سیستمی API های مربوط به خودشو می تونه داشته باشه)، حالا این استفاده کننده هر کی که می خواد باشه، چه کسی باشه که برنامه های کاربردیشو می نویسه و چه کسی باشه که lib ها رو می نویسه و جزئیات رو از دید پنهان می کنه.

----------


## amin32

در مورد for هم من یه پیشنهاد دارم:


for (counter,1,100,+2)

دستورات

revert for


توضیحات:
آرگومان اول یک متغیر شمارنده هست
آرگومان دوم نشان دهنده مقدار شمارنده در شروع حلقه
آرگومان سوم هم حداکثر تعداد تکرار
و آرگومان چهارم که اختیاری هست یرای مشخص کردن step هست که میتونه منفی هم باشه.

نظرت چه؟

----------


## amin32

> نگاه کن اگه بخوای مستقل از Platform عمل کنی نمی تونی یه کد رو برای چند Platform کامپایل کنی. باید برای Windows از API استفاده کنی، برای Lunux از وقفه ی 80h استفاده کنی و برای فلانی فلان کارو کنی. حالا اگه نه بتونی از وقفه استفاده کنی، نه حداقل API تعریف کنی، هیچ کار نمی تونی بکنی. بعدشم قرار نیست توابعی که با API ها یا وقفه ها تعریف می شن رو هر دفعه کاربر تعریف کنه. بلکه باید یه بار اینا رو توی فایل های lib تعریف کنیم. حالا اگه بخوایم یه روال بنویسیم برای چند Platform، باید همین کاری که در زبان C یا زبان های دیگه می کنند رو انجام بدیم، یعنی یه سری If تعریف کنیم که اینا اجرا نشن، فقط کامپایلر موقع کامپایل چکشون کنه یا حالا هر کار دیگه ای... مثلا اگه با FASM کار کنی می بینی که یه کتابخانه ای ساختن برای Windows، Linux و DOS که تو یک کد رو می نویسی و برای Platform های مختلف کامپایل می کنی. اما از کجا می فهمه Platform ات چی می خوای باشه، می بینه که System رو (نام یه ثابت هست) برابر با چی قرار دادی تو برنامت.
> می بینی که هر زبانی (که مستقل از Platform هست) یه روشی رو برای کامپیال کردن واسه Platform مورد نظر، در نظر گرفته. اما در نهایت باید امکان استفاده از امکانات هر Platform وجود داشته باشه که حالا بخواد انتخابی صورت بگیره.
> اگه می خوای مستقل از Platform بنویسیم باید هم بتونه از Interrupt ها استفاده کنه و هم بتونه از API ها استفاده کنه (API ها مختص Windows نیستن هر سیستمی API های مربوط به خودشو می تونه داشته باشه)، حالا این استفاده کننده هر کی که می خواد باشه، چه کسی باشه که برنامه های کاربردیشو می نویسه و چه کسی باشه که lib ها رو می نویسه و جزئیات رو از دید پنهان می کنه.


من با استفاده برنامه نویس از API اصلآ مشکلی ندارم. فقط میگم نباید برای کارهای اصلی زبان مثل خواندن و نوشتن در کنسول, برنامه نویس مجبور باشه از API استفاده کنه.
تو اگه چند زبان به عنوان نمونه بهم نشون بدی که از این روش استفاده میکنند.اونوقت قانع میشم و این کارو منطقی میدونم.

----------


## IamOverlord

> آره خوب.
> 
> فقط یه چیزی... ما مجبوریم فقط از dll های اصلی ویندوز حمایت کنیم.و نمیتونیم از dll های دیگه پشتیبانی کنیم.چون به توابع داخلش و آرگومانهاشون أشنا نیستیم . ولی فکر میکنم چند سال پیش یه راه برای اینکار پیدا کرده بودم.باید بررسی کنیم.


کار های مربوط به Import کردن توابع رو FASM انجام می ده، ما فقط کافیه کد رو تولید کنیم که بهش بگیم Import کن.
مثلا این طوری:

section '.idata' import data readable writeable

  dd 0,0,0,RVA kernel_name,RVA kernel_table
  dd 0,0,0,RVA user_name,RVA user_table
  dd 0,0,0,0,0

  kernel_table:
    ExitProcess dd RVA _ExitProcess
    dd 0
  user_table:
    MessageBox dd RVA _MessageBoxA
    dd 0

  kernel_name db 'KERNEL32.DLL',0
  user_name db 'USER32.DLL',0


البته می تونیم به طور ساده تر از macro استفاده کنیم.

----------


## IamOverlord

> در مورد for هم من یه پیشنهاد دارم:
> 
> 
> for (counter,1,100,+2)
> 
> دستورات
> 
> revert for
> 
> ...


خوبه، ولی یه نظری دارم می تونیم مفهمون For رو با مفهوم مجموعه ها یا ... مرتبط کنیم؟

----------


## IamOverlord

> من با استفاده برنامه نویس از API اصلآ مشکلی ندارم. فقط میگم نباید برای کارهای اصلی زبان مثل خواندن و نوشتن در کنسول, برنامه نویس مجبور باشه از API استفاده کنه.
> تو اگه چند زبان به عنوان نمونه بهم نشون بدی که از این روش استفاده میکنند.اونوقت قانع میشم و این کارو منطقی میدونم.


بعضی زبان هایی که خوندن و نوشتن در Console جزیی از وظایف کامپایلرشون نیست:
اول از همه که خود زبان Assemby مثلا MASM،
زبان C، مثلا ++VC.
و برعکس:
زبان BASIC مثلا QBASIC، برای سادگی این کارو کرده،
زبان Pascal که نمی دونم به خاطر سادگی این کارو کرده یا اون زمانی که نوشتنش شرایط این طوری بوده یا ... .

----------


## amin32

کامپایلر های معروف برای هر سیستم عاملی یک نسخه مخصوص اون دارن. ولی اگه دقت کنی تقریبآ ساختار زبان و دستورات در محیطهای مختلف یکیه.
ببخشیدا!! ولی فکر میکنم این خیلی خنده دار باشه که مثلا تو کتاب آموزش زبان سی بخونی که برای نوشتن در خط فرمان در ویندوز از api استفاده میشه ولی چون تو لینوکس API ویندوز نیست باید از وقفه یا از فایلهای کتابخانه ای استفاده کنی.

----------


## amin32

> بعضی زبان هایی که خوندن و نوشتن در Console جزیی از وظایف کامپایلرشون نیست:
> اول از همه که خود زبان Assemby مثلا MASM،
> زبان C، مثلا ++VC.
> و برعکس:
> زبان BASIC مثلا QBASIC، برای سادگی این کارو کرده،
> زبان Pascal که نمی دونم به خاطر سادگی این کارو کرده یا اون زمانی که نوشتنش شرایط این طوری بوده یا ... .


من منظورم کامپایلری بود که برای نوشتن در خط فرمان, برنامه نویس راه دیگه ای جز استفاده از API نداشته باشه. نه این که در کنار دستورات اصلی خودش بتونی از API هم استفاده کنی.

----------


## IamOverlord

معلومه که خنده داره، چون قراره طرف زبان C رو یاد بگیره، نه نحوه ی کار توابع API ویندوز یا وقفه های Linux. اما حقیتا این طوریه، شما الان یه برنامه ی ساد با ++C بنویس، مثلا من با Dev نوشتم، همون برنامه ی معروف Hello World همیشگی در Console. بعد Compile کن و فایل exe رو در PE Explorer باز کن، ببین توی کدش چی کار کرده، از توابع API موجود در کتابخانه ی [؟] استفاده می کنه.

----------


## IamOverlord

> کامپایلر های معروف برای هر سیستم عاملی یک نسخه مخصوص اون دارن.


آره، ولی اگه یکی بخواد تو محیط Windows فایل برای Linux تولید کنه باید بتونه.

----------


## IamOverlord

> من منظورم کامپایلری بود که برای نوشتن در خط فرمان, برنامه نویس راه دیگه ای جز استفاده از API نداشته باشه. نه این که در کنار دستورات اصلی خودش بتونی از API هم استفاده کنی.


ببینید مثلا در زبان FASM یا MASM یا ... بدون API چه طور می خواید برای Windows برنامه بنویسید؟!

----------


## amin32

> کار های مربوط به Import کردن توابع رو FASM انجام می ده، ما فقط کافیه کد رو تولید کنیم که بهش بگیم Import کن.
> مثلا این طوری:
> 
> section '.idata' import data readable writeable
> 
>   dd 0,0,0,RVA kernel_name,RVA kernel_table
>   dd 0,0,0,RVA user_name,RVA user_table
>   dd 0,0,0,0,0
> 
> ...


ببین باید تمام جوانب رو در نظر گرفت. حالتی رو در نظر بگیر که برنامه نویس از یه تابع که در dll نیست استفاده کنه.خوب در این حالت یعنی ما باید فرض کنیم که تابع درسته و بسپاریم به اسمبلر که اونم با مشکل مواجه میشه و برای فهمیدن مشکل مجبوریم باز در کد اسمبلر دست ببریم که کار رو مشکل میکنه.
در ثانی اصلا شاید منظور برنامه نویس تابع درون dll هم نبود. و کلآ یه تابع تعریف نشده در برنامه بود.اونوقت چی؟؟

ولی همونطور که گفتم این یه راه حل ساده داره که ما میتونیم توابع و آرگومانهای dll رو بدست بیاریم و به این ترتیب این توابع رو از نظر نام و آرگومان بررسی کنیم. و در صورت عدم اشکال به اسمبلر اجازه استفاده از تابع رو بدیم. به همین سادگی.

----------


## maktoom

سلام
موضوع جالبیه!
اول خیلی سطحی صفحه اول و صفحه آخر این تاپیک رو خوندم و خواستم یه نظر دیگه اینجا بنویسم... گفتم بذار کامل بخونمش. فکر نمی کردم اینقدر به این موضوع ساده نگاه کرده باشید.
ببینید یه نمونه خیلی ساده برای درخت تجزیه. ما می خوایم یه قانون بذاریم برای انواع عملیات ضرب و جمع و پرانتز:
E ----> E+E|E*E|(E)|Id
خوب ظاهرا ما یه قانون داریم باهاش می تونیم یه گرامر بسازیم و از روی اون یه درخت پارسر داشته باشیم. اما خیلی زود به این مشکلات بر می خوریم:
اولا برای یک عبارت ممکنه دو تا درخت تجزیه ایجاد کرد. مثلا عبارت id*id+id رو به دو شکل میشه ایجاد کرد و این به تنهایی اثبات کننده گنگ بودن این گرامره. برای گرامر گنگ نمیشه به همین شکل کاری کرد.
ضمن اینکه ما در اینجا چپگردی داریم. چپ گردی به معنای ایجاد تداخل در شروط داخل توابع پیاده سازیه قوانینه. 
خب ما باید اول رفع گنگی بکنیم:
E ----> E+T|T
T----> T*F|F
F----> (E)|id
خب ما با تغییراتی که دایدم تونستیم رفع گنگی بکنیم. اما هنوز رفع چپگردی نکردیم. باید هرجا چپگردی ضمنی هم هست کشف کنیم و گرامر رو عوض کنیم تا بتونیم از ین مرحله سر سلامت رد کنیم.
E---->TE’
E’---->+TE’|ε
T---->FT’
T’---->*FT’|ε
F---->(E)|id

تمام اینکارا رو کردیم تا بتونیم قوانین ضرب و جمع و پرانتز خیلی ساده رو بتونیم بدون تداخل یا چپگردی یا گنگی داشته باشم تا بتونیم با مثلا سی یا هرچیه دیگه پیاده سازی کنیم.
درخت تجزیه بسته به نوع گرامری که انتخاب می کنید(پایین به بالا یا بالا به پایین) قابل بدست آوردنه. در پارس ورودی هر گرامر با استفاده از جدول مربوط به هر نوع گرامر میشه درخت تجزیه رو رسم کرد.
مثال بالا فقط یک مثال بود. ما همین مشکل رو در if و else های متوالی داریم. اونجا هم باید به همین شیوه برخورد کرد.
قدرتمند ترین گرامری که من می شناسم گرامر clr(0) هستش. برای رسیدن به این گرامر باید از پایه درست عمل بشه. 
شما یکسری توانایی های خوبی دارید. من هم قبول دارم. اما اینها هیچ ربطی به کاری که براش آستین بالا زدید نداره.
شما API رو خوب بلدید کار با زبان VB رو هم خوب بلدید یا هر ابزار دیگه رو... خوب اینا چه ارتباطی با مفاهیم ایجاد یک کامپایلر داره. 
پیشنهاد من اینه: بطور عمقی... خیلی بیشتر از چیزایی که برای نمره احتمالا بالایی که در این درس آوردید... مطلب بخونید. با اساتیدتون بطور تنگاتنگ ارتباط برقرار کنید. مطمئن باشید می تونید اگر دانشجو هستید بعنوان پروژه پایانی روش سرمایه گذاری کنید یا حداقل یه مقاله ای چیزی باهاش بدید. یه کاری که ارزش داشته باشه و انگیزه هم به اندازه کافی ایجاد کنه. اگر هم دانشجو نیستید یه تجربه بسیار عالیه. البته رایگان هم نخواهد بود.(انرژی و زمان)
گذشته از این مفاهیم شما رو دعوت می کنم به بررسی زبان هایی مثل RUBY. زبانی کاملا متفاوت با چیزایی که تابحال دیدید(البته اگه اینو ندیده باشید.)
 اصلا در چه حیطه ای می خواید زبان ایجاد کنید. در حیطه ی هوش مصنوعی. در حیطه شی گرایی در حیطه ارتباط با سرور یا... . شما بنظر دارید چیزایی که دیدید رو اینبار اونجور که می خواید تغییر می دید. خوب؟ بهبودش کجاست؟ چه معنای جدیدی رو قراره بهش اضافه کنید؟ چه ایده خلاقانه ای براش درنظر گرفتید؟ و از همه مهمتر در کجا قصد دارید ازش استفاده کنید. چه حیطه ای؟
کار، کار پر بار و خوش محصولیه. اما اگر اصولی از ابتدا پیش برید به نتیجه می رسید. مطالب و سر فصل های منابع اصلی اصول طراحی زبانهای برنامه نویسی و مفاهیم طراحی کامپایلر ها می تونه واقعا مفید باشه. مثه یه نقشه راه. اما بسیار بیشتر از اینکه تابحال کار کردید باید عمیق بشید.
قدری دانش Exploid هم یاد بگیرید تا در طراحی کدهاتون بتونید مشکلاتی که بعضی زبانها دارن رو به حداقل برسونید.
شاید برای شروع کمی زیاد اوج گرفتید. فعلا زمان یادگرفتنه. اصلا تابحال فکر کرده بودید چرا یه زبان نیاز به قوانین و گرامر داره. ماشیا آتاماتا به چه درد می خوره. NFAو DFA چه ربطی به زبانهای برنامه نویسی دارن. چرا آقای نوام چامسکی که یک زبان دان و فیلسوف هست و بعنوان پدر زبانشناسی مدرنه همچنین درمورد روانشناسی تالیفاتی داره... چرا این آدم نظریه هایی در مورد زبانشناسی اونم در حیطه زبانهای کامپیوتری داده؟
وقتی داشتم در مورد انواع زبان برنامه نویسی موازی تحقیق می کردم این اسم رو مدام می دیدم Per Brinch Hansen
این شخص آدم جالبیه و در آزمایشگاهش زبانهای زیادی رو تولید و گسترش داده. (پاسکال یکیشه...)
بنظرم مطالعه در مورد روش کار این آدم و کارهایی که کرده می تونه مفید باشه.
شرطها و حلقه ها وامثال اینها واقعا مسائل و مفاهیمی هستن که باید پایه ای تر بهشون فکر کنید. اینکه چطور پیاده سازی بشن مسئله شما نیست. مسئله شما اینه که چطور قراره مفاهیمش رو پیاده کنید. فقط خود همین if و else های متوالی رو کمی بیشتر درموردش فکر کنید. شما یه برنامه می نویسید کلی باگ و ارور و وارنینگ داره حالا چطور از همون روش می خواید استفاده کنید برای طراحی یک کامپایلر که خودش باید اینا رو تشخیص بده؟
حالا اینا به کنار. کاربر یه گرامر غلط وارد می کنه. چطور می خواید درستش رو بهش بگید؟ یعنی در ارور یا وارنینگ چه گزارش خطایی باید ثبت بشه؟ چه عبارتی پیشنهاد بشه؟ اصلا چه سیاساتی باید اعمال بشه؟ حذف از ورودی تا درست شدن گرامر یا کامپایل کردن بقیه کد و درنهایت دادن یک گزارش کلی... 
تابحال به این فکر کردید کامپایلر زبانی مثلا مثل جاوا رو با چی نوشتن؟ و اگه با هرچی نوشتن پس باید کامپایلر اون زبان هم داخل کامپایلر جاوا تعبیه شده باشه؟(منظورم اینجا اسمبلی نیست)
قصدم ازطرح این مطالب و سوالات به معنای سنگ اندازی یا دادن حس ناامیدی نیست.  بلکه جدا با این شوری که در این حدود 120 تا پستی که خوندم دیدم گفتن این مطالب لازمه. 
اگه دانشگاه هستید با 3  تا استاد حتما صحبت کنید. استاد درس PL و استاد درس نظریه زبانها و ماشینها  و استاد درس اصول طراحی کامپایلرها. اگه کسی رو می شناسید که توی هر 3 تای اینا دستی داره قدرش رو بدونید.
براتون آرزوی موفقیت می کنم.

----------


## amin32

> معلومه که خنده داره، چون قراره طرف زبان C رو یاد بگیره، نه نحوه ی کار توابع API ویندوز یا وقفه های Linux. اما حقیتا این طوریه، شما الان یه برنامه ی ساد با ++C بنویس، مثلا من با Dev نوشتم، همون برنامه ی معروف Hello World همیشگی در Console. بعد Compile کن و فایل exe رو در PE Explorer باز کن، ببین توی کدش چی کار کرده، از توابع API موجود در کتابخانه ی [؟] استفاده می کنه.


من نمیدونم شاید منظورتون رو از استفاده از API برای کارهای ساده  بد متوجه شدم. اگه منظورتون استفاده ما برای پیاده سازی و در مرحله ایجاد کد اسمبلی هست و برنامه نویس کاری به اون نداره, من اشکالی نمیبینم. ولی اگه منظورتون اینه که برنامه نویس مجبور باشه برای انجام کارهای ساده ای مثل نوشتن در خط فرمان از API استفاده کنه, کاملآ مخالفم.

----------


## amin32

> سلام
> 
> E ----> E+E|E*E|(E)|Id
> خوب ظاهرا ما یه قانون داریم باهاش می تونیم یه گرامر بسازیم و از روی اون یه درخت پارسر داشته باشیم. اما خیلی زود به این مشکلات بر می خوریم:
> براتون آرزوی موفقیت می کنم.


خوب این که بازگشتی چپ داره که باید رفع بشه.
اما باقی مطلبتو یه نیم ساعت دیگه میخونم.

----------


## amin32

> سلام
> موضوع جالبیه!
> اول خیلی سطحی صفحه اول و صفحه آخر این تاپیک رو خوندم و خواستم یه نظر دیگه اینجا بنویسم... گفتم بذار کامل بخونمش. فکر نمی کردم اینقدر به این موضوع ساده نگاه کرده باشید.
> ببینید یه نمونه خیلی ساده برای درخت تجزیه. ما می خوایم یه قانون بذاریم برای انواع عملیات ضرب و جمع و پرانتز:
> E ----> E+E|E*E|(E)|Id
> خوب ظاهرا ما یه قانون داریم باهاش می تونیم یه گرامر بسازیم و از روی اون یه درخت پارسر داشته باشیم. اما خیلی زود به این مشکلات بر می خوریم:
> اولا برای یک عبارت ممکنه دو تا درخت تجزیه ایجاد کرد. مثلا عبارت id*id+id رو به دو شکل میشه ایجاد کرد و این به تنهایی اثبات کننده گنگ بودن این گرامره. برای گرامر گنگ نمیشه به همین شکل کاری کرد.
> ضمن اینکه ما در اینجا چپگردی داریم. چپ گردی به معنای ایجاد تداخل در شروط داخل توابع پیاده سازیه قوانینه. 
> خب ما باید اول رفع گنگی بکنیم:
> ...


دوست عزیز ممنون از نظرتون. راستش اینقدر که کاربر دیگه ای رو در تاپیک نداشتیم اولش شما رو با اون دوست همیشگی اشتباه گرفتم.به هر حال ببخشید.
می خوام یه جواب کلی به نظراتتون بدم.البته اگه روی سخنتون با من بود. ببینید این مسا‌ئلی که فرمودید کاملا درست بود اما فکر میکنم که الان زمان حل این مشکلات نیست. مثلا بحث گرامرهای مبهم رو برای دستورات شرطی درنظر بگیرید.ما وقتی هنوز ساختار دستورات شرطیمون مشخص نیست چطور باید به فکر حل این مشکل باشیم.شاید شاید شاید ساختاری که ما طراحی کردیم اصلا مشکل ابهام نداشته باشه.در مورد نحوه برخورد با خطاها هم به همین شکل(پوشش خطا یا توقف). من نظرم این بود که اول بدنه اصلی ساختار نحوی مشخص بشه. و بعد به این مشکلات رسیدگی کنیم و یا حتی در صورت لزوم ساختار نحوی رو تغییر بدیم. ولی در کل با شما موافقم که باید در مورد ساختارهای اصلی مثل ساختار شرطی و..... به شکل عمیقتری بحث بشه.بازم ممنون.


در ضمن انصافآ نوام چامسکی رو نمیشه فقط در زبانشناسی و روانشناسی خلاصه کرد. اون رو میشه در خیلی از عرصه های علمی یا غیر علمی یک اسطوره در عصر حاضر دونست.

----------


## maktoom

ترجیه می دم بجای جواب کلی قدری بیشتر به نکات مختلفی که طرح کردم فکر کنید.
تاحالا چند بار در این فروم در تاپیکهای مختلف استارت طراحی یه کامپایلر کوچیک یا بزرگ و یا بخشی از اون زده شده و دفعاتی که من پیگیرش بودم موفقیتی ندیدم دقیقا به همین دلایلی که عرض کردم.
مهمترین چیزی که دوس داشتم بعد خوندن مطلب بالا بنظر برسه اینه که مسلط بودن بر tools فرق اساسی با مسلط بودن به یک دانش داره.
و این دقیقا اولین مشکلیه که در طراحی یک کامپایلر راه رو به بیراهه می بره. پروژه های نیمه کاره... افراد با استعداد ناامید ... .
همین ساختارهای شرطی و ... اینها بعد از خیلی از مفاهیم پایه ایه نوع زبانتون مشخص میشه.

----------


## amin32

> ترجیه می دم بجای جواب کلی قدری بیشتر به نکات مختلفی که طرح کردم فکر کنید.
> تاحالا چند بار در این فروم در تاپیکهای مختلف استارت طراحی یه کامپایلر کوچیک یا بزرگ و یا بخشی از اون زده شده و دفعاتی که من پیگیرش بودم موفقیتی ندیدم دقیقا به همین دلایلی که عرض کردم.
> مهمترین چیزی که دوس داشتم بعد خوندن مطلب بالا بنظر برسه اینه که مسلط بودن بر tools فرق اساسی با مسلط بودن به یک دانش داره.
> و این دقیقا اولین مشکلیه که در طراحی یک کامپایلر راه رو به بیراهه می بره. پروژه های نیمه کاره... افراد با استعداد ناامید ... .
> همین ساختارهای شرطی و ... اینها بعد از خیلی از مفاهیم پایه ایه نوع زبانتون مشخص میشه.


به نظرتون احترام میگذارام اما باز فکر میکنم شما تمام تاپیک رو نخوندید و دارید در مورد من قضاوت میکنید.

https://barnamenevis.org/showthread.p...=1#post1421219

----------


## amin32

این رو هم اضافه کنم که من استارت پروژه رو نزدم و اینجام تا زمانی که وقت آزاد دارم و تا جایی که بتونم  در این مورد راهنمایی کنم.
اما به نظر من اصلا منطقی به نظر نمیاد وقتی هنوز ساختار زبان شخص نیست بیایم تصمیم بگیریم که مثلآ از (LALR(1 استفاده کنیم یا از (clr(0 یا حتی اگه بهینگی برامون زیاد اهمیتی نداشت شاید (LR(1

----------


## maktoom

همه 140 پست رو خوندم. فایلهای ضمیمه شده رو هم دانلود کردم اما هنوز ندیدم. ولی اینا و همه اینایی که گفتم رو به خودتون و شخصتتون نگیرد من جدا دوست دارم شما در این تاپیک موفق بشید.
من جرات اینکه اینجا قضاوتی بکنم ندارم. چه اینکه بارها در برخی از پستها از خودم پرسیدم من اصلا در مورد مقطع تحصیلی و یا دانش این دوستان اطلاعی ندارم. شاید اینا که بگم قدری از سطح دوستان پایینتر باشه.
لینک این صفحه رو به دوستان و اساتیدی که می شناسم می دم تا نظر اونها رو بدونم.
شما هم بحث رو گسترش بدید.

----------


## IamOverlord

خوب خیلی خوب شد، از 3 نفر کار بیش تری بر می آد ... .
ببینید در مورد تسلط به ابزار و کد مقصد و ...، فکر نمی کنم مشکلی باشه.
فقط باید تمام فکر و ذکرمونو، بذاریم رو این که چه طور یه کامپایلر رو بر اساس مفاهیم و روش های استانداردی که هست، پیاده سازی کنیم. اتفاقا این که شما یه سری مسائل و مشکلات رو از قبل در میون می ذارید خیلی خوبه، این باعث می شه که کارو با احتیاط بیش تری ادامه بدیم، و خیلی دوست دارم که این قضیه ی گوشزد کردن مشکلات (نه ناامید کردن) ادامه پیدا کنه.
حالا قبل از این که به هر مشکلی در زمینه ی طراحی بر بخوریم، به نظرم اول باید بفهمیم چیو می خوایم طراحی کنیم و با چی روبه رو هستیم.
در مورد مسائل تئوری هم من همزمان دارم سعی می کنم بیش تر و بیش تر بفهمم، از روی کتاب ها برم جلو.
امیدوارم از تجربه های هم استفاده کنیم و با مشارکت هم بریم جلو.
موفق باشیم!/

----------


## amin32

دوست عزیز لطف کن و تمام ساختارهایی که به توفق رسیدیم رو جمع آوری کن و قرار بده.
فقط من هنوز روی than مربوط به if مشکل دارم و میخوام تغییر کنه مثلا ':' که قبلا هم گفتم.

----------


## IamOverlord

Function main() : Integer

End Function

Procedure PrintString(StringAddress : Pointer To String)

End Procedure

Do While a <> b :

Loop

Do For i = 1 To 10 Step 2 :

Loop

Do Until a = b :

Loop

If a <> b :

End If

Public i : Integer
Public j : Unsigned Integer
Private p : Pointer To Integer
Private M(1 To 10) : Integer
text1 : String
test2(1 To 100) : Character
a : Byte
Apple : Fruit
Orange : Fruit
blnVariable : Boolean

Select blnVariable
Case True :

Break 1
Case False :

Break
Case Not True :

Case Else :

End Select


If i = j :

Else If b = True : 

Else :

End If


AddressOfVariable1 = &Variable1
ValueOfVariable1 = @AddressOfVariable1


Import Function “DeleteDC” From “GDI32.DLL” As DelDC (ByVal hdc : Long) : Long

blnVariable = (a = b)?

----------


## amin32

> Function main() : Integer
> 
> End Function
> 
> Procedure PrintString(StringAddress : Pointer To String)
> 
> End Procedure
> 
> Do While a <> b :
> ...


لطفآ ویرایشش کنید چون در مورد select و حلقه ها هنوز اتفاق نظر نیست

----------


## IamOverlord

اگه چبزی رو کم گذاشتم یا اشتباه، چک کنید تغییر بدید... :چشمک:

----------


## amin32

> اگه چبزی رو کم گذاشتم یا اشتباه، چک کنید تغییر بدید...


اینجور که من میبینم روی خیلی مسائل هنوز اتفاق نظر نیست. مثل تعریف متغیر که نظر من اینه :
variable i :integer

اما مثل اینکه شما نظر دیگه ای دارید. :متفکر:

----------


## IamOverlord

خوب پس برای متغیر ها از Variable استفاده کنیم و برای اشیاء هم از Object.

----------


## IamOverlord

در مورد تعریف چیزای جدید:
1. تعریف Struct (این کار که مثل آب خوردنه! چون در FASM تعریف Struct به راحتی تعریف متغیر هست  :لبخند گشاده!: )
2. تعریف Type (تعریف انواع داده ی جدید. مثل VB6 با Struct ادغامش کنیم یا ... ؟)
3. تعریف Object از روی Class
در مورد سومی یه ابهاماتی داشتم که برطرف شد.
می تونیم برای مرحله ی اول حداقل تا یه حدودی پیاده سازیش کنیم.
بر اساس اون چه که در مورد C With Classes خوندم، این کارو می تونیم بکنیم:
بیایم از داده های Class یه Struct تعریف کنیم، بعد هر بار که Object ای جدید از اون نوع Class تعریف می شه یه Struct جدید بسازیم برای اون Object جدید،
برای توابع و روال های تمام Object ها یه سری توابع و روال های مشترک در نظر می گیریم که به همشون یه پارامتر ورودی جدید اضافه می کنیم: آدرس Struct ای که Object مورد نظرمون داره.

----------


## amin32

use "iostream.lib"		به کار بردن کتابخانه

Import Function “DeleteDC” From “GDI32.DLL” As DelDC (ByVal hdc : Long) : Long		API معرفی

define:
	variable e:integer
	variable f:sinteger
	variable g:binteger
	variable h:float			تعریف متغیرهای عمومی
	variable i:bfloat
	variable j:char
	variable k:str
end define 


Function main() : Integer		تابع اصلی
   M = x * y
End Function

Function Multiply(x : Integer, y : Integer) : Integer	 توابع فرعی
   Multiply = x * y
End Function

If a <> b :
 					شرط ساده
End If


If i = j :

If b = True : 			شرط تودرتو

End If

Else :

End If


لطفآ اگر اشکالی میبینید الان اعلام کنید و نگذارید برای بعد.

----------


## IamOverlord

آه! نگرانیم بر طرف شد  > cs.saddleback.edu/ccarroll/CS3B/Slides3B/Section10.pdf

----------


## IamOverlord

خوب من با همه جاش موافقم، فقط در مورد define یه مسئله هست:
وقتی برنامه نویس متغیر ها رو در کلاس یا هر جای دیگه ای که تعریف می کنه می خواد که Public یا Private باشن، که مجبوریم این کلمات کلیدی رو قبل از Variable بیاریم، خوب چرا یهو نیایم برای تعریف متغیر های عمومی از همون Public قبل از Variable استفاده کنیم؟

----------


## amin32

> در مورد تعریف چیزای جدید:
> 1. تعریف Struct (این کار که مثل آب خوردنه! چون در FASM تعریف Struct به راحتی تعریف متغیر هست )
> 2. تعریف Type (تعریف انواع داده ی جدید. مثل VB6 با Struct ادغامش کنیم یا ... ؟)
> 3. تعریف Object از روی Class
> در مورد سومی یه ابهاماتی داشتم که برطرف شد.
> می تونیم برای مرحله ی اول حداقل تا یه حدودی پیاده سازیش کنیم.
> بر اساس اون چه که در مورد C With Classes خوندم، این کارو می تونیم بکنیم:
> بیایم از داده های Class یه Struct تعریف کنیم، بعد هر بار که Object ای جدید از اون نوع Class تعریف می شه یه Struct جدید بسازیم برای اون Object جدید،
> برای توابع و روال های تمام Object ها یه سری توابع و روال های مشترک در نظر می گیریم که به همشون یه پارامتر ورودی جدید اضافه می کنیم: آدرس Struct ای که Object مورد نظرمون داره.



فعلا اولویت با حلقه ها و ساختار switch هست

----------


## IamOverlord

خوب حلقه ها که تعریف شد فکر کنم ...
اما فکر کنم هنوز تکلیف Select Case معلوم نشد.

----------


## amin32

> خوب من با همه جاش موافقم، فقط در مورد define یه مسئله هست:
> وقتی برنامه نویس متغیر ها رو در کلاس یا هر جای دیگه ای که تعریف می کنه می خواد که Public یا Private باشن، که مجبوریم این کلمات کلیدی رو قبل از Variable بیاریم، خوب چرا یهو نیایم برای تعریف متغیر های عمومی از همون Public قبل از Variable استفاده کنیم؟


ببین سادست! متغیرهایی که قراره تو تمام توابع در برنامه استفاده بشن(public) داخل بلاک define قرار میگیره
متغیرهایی که قراره فقط در یک تابع استفاده بشن (private) داخل همون تابع تعریف میشن
متغیرهایی هم که قراره در کتابخانه ها تعریف بشن و در برنامه اصلی استفاده شن به این شکل:

share:
variable i : integer
end share

----------


## amin32

الان شما با کدهای پست ۱۵۱ مشکل دارید؟

----------


## IamOverlord

خوب خوبه... :متفکر:

----------


## IamOverlord

در مورد انواع داده ی اولیّه، این جا رو بررسی کن... :متفکر:

----------


## amin32

> خوب حلقه ها که تعریف شد فکر کنم ...
> اما فکر کنم هنوز تکلیف Select Case معلوم نشد.


فکر میکنم در مورد حلقه فقط نظر داده بودیم و منم در مورد for  نظرم روی این بود.


for (counter,1,100,+2)

دستورات

revert for

----------


## amin32

> خوب خوبه...



پس اگه واقعآ مشکلی نیست لطفآ اون رو جایی برای خودتون ذخیره کنید و دیگه روش تغییری ندیدید. باز میگم اگه مشکلی باهاش ندارید.

----------


## IamOverlord

حلقه ی for زبان C قوی تره و خیلی هم شبیه به اینه.

----------


## IamOverlord

به نظرم بهتره ساختار for مون هر چی که هست از این شکل تبعیت کنه :

Do ...

Loop

----------


## amin32

> به نظرم بهتره ساختار for مون هر چی که هست از این شکل تبعیت کنه :
> 
> Do ...
> 
> Loop


من اصلا درک نمیکنم چرا شما در تمام ساختار ها اولین چیزی که به ذهنتون میرسه ساختار زبان basic هست. یکم خلاقیت هم بد نیست. نمونه بازش همون ساختار توابع که فقط به جای as در پارامترها از ":" استفاده شده.

----------


## amin32

> حلقه ی for زبان C قوی تره و خیلی هم شبیه به اینه.



اگه منظورتون اینه:



for (counter,1,100,+2)

دستورات

revert for


این کجاش شبیه C هست. البته من روی لغت revert از لحاظ مفهومی شک دارم

----------


## IamOverlord

for i from 1 to 10 step 2

check for i

این هم قدرتش مثل ساختار for زبان C هست:
for i=0 until i=10 : i++

revert for

...

----------


## IamOverlord

عیب نداره.
ولی بیش تر می خواستم این ویژگی خوب زبان Pascal رو داشته باشیم:

Syntactically, Pascal is much more Algol-like than C. English keywords are retained where C uses punctuation symbols — Pascal has and, or, and mod where C uses &&, ||, and % for example. However, C is actually more Algol-like than Pascal regarding (simple) declarations, retaining the type-name variable-name syntax. For example, C can accept declarations at the start of any block, not just the outer block of a function.
از این که به جای end و next و ... از یه چیز متفاوت مثل revert استفاده کردید خوشم اومد. از لحاظ مفهومی می تونیم به جاش از check for i هم استفاده کنیم، چون به این معناست که همیشه بر نمی گرده به ابتدای حلقه و check می کنه.

----------


## amin32

> for i from 1 to 10 step 2
> 
> check for i
> ...


این شد یه چیزی... فقط step یکم بینظمش کرده و همچنین check for i یکم بی معنی به نظر میاد. :متفکر:

----------


## IamOverlord

خوب استفاده از step اختیاری هست و نیازی نیست همیشه استفاده کنه. مثلا در حالت عادی:
For i From 1 To 10

Check For i

منظور از Check For i هم این هست که : شرط ادامه ی حلقه رو برای i چک کن و ...

----------


## amin32

> خوب استفاده از step اختیاری هست و نیازی نیست همیشه استفاده کنه. مثلا در حالت عادی:
> For i From 1 To 10
> 
> Check For i


 همین خیلی خوبه. اینو به ساختارهای قبلی اضافه کنید. مرحله بعدی ساختار یک نوع حلقه while ....

----------


## IamOverlord

خوب برای ساختار While بد نیست این جا رو هم نیگا بندازید.

----------


## aminghaderi

با تشکر و خسته نباشید خدمت دوستان ساعی و پرتلاش.
دوستان هر چند پست یه گزارش کار هم بدید که مثلا تا حالا به کجا رسیدید.
من سر از طراحی کامپایلر در نمی یارم ولی بحث شما رو دنبال می کنم ، موفقیت شما برام مهم هست.
با تشکر.

----------


## amin32

> با تشکر و خسته نباشید خدمت دوستان ساعی و پرتلاش.
> دوستان هر چند پست یه گزارش کار هم بدید که مثلا تا حالا به کجا رسیدید.
> من سر از طراحی کامپایلر در نمی یارم ولی بحث شما رو دنبال می کنم ، موفقیت شما برام مهم هست.
> با تشکر.


با سپاس از نظر و توجهتون.
درمورد گزارش کار باید عرض کنم که خودم هم خیلی به نظم در چنین پروژه هایی اهمیت میدم و ارائه گزارش کار هم میتونه یکی از راههای منظم نگه داشت پروژه باشه.اما با توجه به محدودیتهای زمانی که من با اونها مواجه هستم شاید نشه آنچنان روی این مسائل وقت گذاشت. ولی سعی میکنیم حداقل در بازه های زمانی طولانی (البته اگر کارها به همین شکل پیش بره) گزارش کار هم ارائه بدیم.
بازم ممنون.

----------


## IamOverlord

۱- ساختار تعریف متغیر
۲- ساختار تعریف توابع
۳- ساختار نحوی عملگرها و دستورات محاسباتی
۴- ساختارهای شرطی
۵- ساختار حلقه و تکرار
------------------------------------------------------
خوب الان یه چیز حدودی ای دستمون اومده، به نظرم الان خیلی ساده همین هایی که گفتیم رو مشخص کنیم و پیاده سازی کنیم. دوباره که می یایم تغییر بدیم و بهترش کنیم، ایده های جدید رو هم پیاد سازی می کنیم.
نظر شما چیه؟

----------


## amin32

> ۱- ساختار تعریف متغیر
> ۲- ساختار تعریف توابع
> ۳- ساختار نحوی عملگرها و دستورات محاسباتی
> ۴- ساختارهای شرطی
> ۵- ساختار حلقه و تکرار
> ------------------------------------------------------
> خوب الان یه چیز حدودی ای دستمون اومده، به نظرم الان خیلی ساده همین هایی که گفتیم رو مشخص کنیم و پیاده سازی کنیم. دوباره که می یایم تغییر بدیم و بهترش کنیم، ایده های جدید رو هم پیاد سازی می کنیم.
> نظر شما چیه؟


الان متوجه منظورتون نشدم. میگید همین ها رو پیاده سازی کنیم یا الان بیایم اصلاحشون کنیم؟؟

----------


## IamOverlord

پیاده سازی کنیم...

----------


## amin32

موافقم
پس اول باید به تحلیلگر لغوی بپردازیم.
خوب عبارات باقاعده زبانمون :

۱- شناسه:*[9-a-z][a-z 0]

۲- اعداد صحیح:*[9-0][9-0]

۳-اعداد اعشاری:[9-0].*[9-0][9-0]

۴-رشته:"*[all ascii code]"

در ضمن کلمات کلیدی هم جزء شناسه ها هستند.

----------


## IamOverlord

خوب الان مثلا در تابع تحلیلگر لغوی،
خروجی اش لغت جدید باشه به علاوه ی نوع اون؟

----------


## IamOverlord

یه کاری می گم برای راحتی خودمون، می تونیم قسمتی از کار Compiler رو با macro ها تو Assembler بکنیم. یعنی مثلا فرض کن برای انتساب 2 متغیر رشته ای باید n خط کد تولید کنیم، حالا ما می آیم این n خط رو به صورت macro برای Assembler تعریف می کنی و فقط قسمتی از کار رو در مراحل قبل در کامپایلرمون انجام می دیم. البته اونی که گفتم مثال بود، حالا کارای مهم تری هم می شه کرد.

----------


## amin32

> یه کاری می گم برای راحتی خودمون، می تونیم قسمتی از کار Compiler رو با macro ها تو Assembler بکنیم. یعنی مثلا فرض کن برای انتساب 2 متغیر رشته ای باید n خط کد تولید کنیم، حالا ما می آیم این n خط رو به صورت macro برای Assembler تعریف می کنی و فقط قسمتی از کار رو در مراحل قبل در کامپایلرمون انجام می دیم. البته اونی که گفتم مثال بود، حالا کارای مهم تری هم می شه کرد.


میدونم شاید یکم سختگیرم ولی لازمه این نکته رو بگم که بهتره پراکنده کار کنیم. یعنی وقتی قراره روی تحلیلگر لغوی کار کنیم, فعلآ به مسائل دیگه فکر نکنیم.

----------


## amin32

> خوب الان مثلا در تابع تحلیلگر لغوی،
> خروجی اش لغت جدید باشه به علاوه ی نوع اون؟


خروجی : نوع لغت و خود لغت . همچنین باید جدول نماد رو پایه گذاری کنیم و تمام شناسه ها به غیر از کلمات کلیدی رو در اون قرار بدیم. که این جدول برای هر شناسه یک قسمت صفت هم داره که باید در فازهای بعد تکمیل بشه.
وقتی سرم خلوت شد سعی میکنم روش کار کنم.

----------


## maktoom

سلام
خب مثه اینکه بعد از تمام بحثهای اولیه(و البته مهم) به جایی که مورد علاقه بنده است، رسیدید.
ثابتهای عددی تشکیل شدن از اعداد صحیح و اعداد اعشاری و اعداد اعشاری با نماد علمی که همه اینها علامت دار هستند. (بدون علامت یعنی علامت مثبت)
اینها رو باید از روی دیاگرام انجام داد. اول باید گرامرش رو بدست آورد از روی گرامر nfa اون رو رسم کرد وبعد اونو خیلی راحت به dfa تغییر شکل داد.(این بمعنی تبدیل nfa به dfa نیست)
تموم این کارا انجام میشه تا شاکله کار بدست بیاد.
درمورد شناسه ها... اول باید کلمات کلیدی در یک جدول قرار داده بشن به ترتیبی که یک کلیدبراشون تعریف بشه. این جدول همون جدولیه که باید تمام شناسه ها بهمراه نوعشون(توکنها) در صورت جدید بودن ذخیره بشن.
کلیدی که بهش اشاره کردم برای اینه که معلوم کنه شناسه پیدا شده از کلمات کلیدیه زبان هست یا نه. درصورت یک بودن کلید دیگه اون رو در جدول بعنوان شناسه قرار نمیدیم.
تا اینجا یک چیز مشخصه: تعیین توکنها باید ترتیب خاصی داشته باشه به نحوی که انواع پرکاربرد و طولانیتر زودتر تست بشن تا مشکلی پیش نیاد.
توضیحات و جاهای خالی که حذف میشن.
شناسه ها هم که کاملا بستگی به نوع تعریفتون در این زبان داره.
ثابتهای دیگه بجز عددی ها یعنی رشته ها هم باید تعریف کنید می خواید مثه سی داخل یک جفت " باشه یا جور دیگه.
خب خروجی این بخش توکنهایی خواهند بود که باید در جایی ذخیره بشن برای مرحله بعد.

----------


## mr.gigil

سلام

فکر می کنم حدود یک ساعت و شاید بیشتر وقت گذاشتم و کل تاپیک رو خودنم (تا این لحظه) 

خوب خیلی از چیزها رو که مطرح شد نمی دونستم، اما قطعا علاقه مند هستم که بحث رو دنبال کنم. امیدوارم که فرصت و علم من رو یاری کنند که من هم بتونم اظهار نظری مفید کنم.

با تشکر از دوستان

----------


## IamOverlord

نقطه ای که بین دو شناسه می ذاریم و اونا رو به هم متصل می کنه، اون چی؟ جدا حساب می شه...؟
اگر کاربر برنامه رو به هم چسبیده نوشت (طوری که کد درست خونده بشه)، برای ما ممکنه مشکلی در تحلیل لغوی پیش بیاد؟
خط جدید در تحلیل لغوی؟!
تحلیل لغوی می تونه یک بار از اول تا آخر پشت سر هم انجام بشه یا ممکنه نیاز باشه لغت های جلو تر از یه لغت رو هم تحلیل کرد؟

----------


## amin32

> نقطه ای که بین دو شناسه می ذاریم و اونا رو به هم متصل می کنه، اون چی؟ جدا حساب می شه...؟
> اگر کاربر برنامه رو به هم چسبیده نوشت (طوری که کد درست خونده بشه)، برای ما ممکنه مشکلی در تحلیل لغوی پیش بیاد؟
> خط جدید در تحلیل لغوی؟!
> تحلیل لغوی می تونه یک بار از اول تا آخر پشت سر هم انجام بشه یا ممکنه نیاز باشه لغت های جلو تر از یه لغت رو هم تحلیل کرد؟


1-در مورد نقطه: اصلا ما یک چنین ساختاری در زبانمون نداریم!
2-میتونیم از روشی که زبانی مثل ویژوال بیسیک استفاده میکنه , برای حل این مشکل استفاده کنیم.مثلآ i=1+1 رو به i = 1 + 1 تبدیل کنیم.
3- در هر زبانی از یک کاراکتر به عنوان هماهنگ کننده استفاده میشه.(مثل ; در زبان سی) و در زبان ما کاراکتر خط جدید این وظیفه رو داره.
4-از هر یک از دو راهبرد میشه استفاده کرد.ولی من از روش اول برای نوشتن تحلیلگر استفاده میکنم.

لطفآ فعلآ شما روی گرامر های مستقل از متن و تحلیلگر نحوی مطالعه و تمرکر کنید.

----------


## maktoom

از چه تحلیلگر نحوی می خواید استفاده کنید؟

----------


## IamOverlord

منظورتون تولید کنندشه؟

----------


## maktoom

شما برای نشتن تحلیلگر لغوی از چه ابزاری استفاده خواهید کرد؟ این هم هنوز برای من مفهوم نیست.
خب حالا بر فرض این تحلیلگر رو نوشتید.
از چه گرامری برای انجام تحلیلگر نحوی می خواید استفاده کنید؟ از انواع بالا به پایین یا پایین به بالا؟ (این در مفهوم ساخت درخت تجزیه تعیین میشه یعنی از ریشه به سمت برگ یا از برگ به سمت ریشه)
پایین به بالا راحتتتره. تا چه حد دقت و ظرافت کار براتون مهمه؟
یه بار گرامر تقدم عملگر توی این تاپیک مفصلا در موردش بحث شده.
اما این فقط یکیشه.

----------


## amin32

> شما برای نشتن تحلیلگر لغوی از چه ابزاری استفاده خواهید کرد؟ این هم هنوز برای من مفهوم نیست.
> خب حالا بر فرض این تحلیلگر رو نوشتید.
> از چه گرامری برای انجام تحلیلگر نحوی می خواید استفاده کنید؟ از انواع بالا به پایین یا پایین به بالا؟ (این در مفهوم ساخت درخت تجزیه تعیین میشه یعنی از ریشه به سمت برگ یا از برگ به سمت ریشه)
> پایین به بالا راحتتتره. تا چه حد دقت و ظرافت کار براتون مهمه؟
> یه بار گرامر تقدم عملگر توی این تاپیک مفصلا در موردش بحث شده.
> اما این فقط یکیشه.


همون طور که قبلآ هم گفتم استفاده از ابزارهای ساخت تحلیلگر, انعطاف پذیری رو خیلی پایین میاره. و دارم سعی میکنم تحلیلگر لغوی رو مستقیمآ با زبان ویژوال بیسیک بنویسم.
اگه منظورتون از گرامر  پایین به بالا همون تجزیه کننده پایین به بالا هست, باید عرض کنم به خاطر درگیر بودن با تحلیلگر لغوی هنوز تصمیمی در این مورد گرفته نشده.

----------


## mr.gigil

سلام.

من خیلی دوست دارم که بیشتر درباره مطالبی که اینجا میگذارید بدونم. 
کتابی به زبان فارسی می شناسید که بتونید به من معرفی کنید. ترجیحا، الکترونیکی باشه بهتره. 

دوست دارم که با دید بهتری این تاپیک رو دنبال کنم.

----------


## IamOverlord

الان کی تحلیلگر لغوی رو می نویسه؟ من بنویسم؟ دقیقا چی ... ؟

----------


## amin32

> سلام.
> 
> من خیلی دوست دارم که بیشتر درباره مطالبی که اینجا میگذارید بدونم. 
> کتابی به زبان فارسی می شناسید که بتونید به من معرفی کنید. ترجیحا، الکترونیکی باشه بهتره. 
> 
> دوست دارم که با دید بهتری این تاپیک رو دنبال کنم.



سلام دوست عزیز.
راستش کتابی رو به اون صورت نمیتونم بهتون معرفی کنم. ولی فقط این رو بگم که کلآ کامپایلر ارتباط زیادی با مبحث نظریه زبان ها و ماشینها داره. در نتیجه توصیه من اینه که هر کتابی با موضوع نظریه زبانها و همچنین اصول طراحی کامپایلر میتونه مفید باشه.
شاید با جستجو در اینترنت بتونید مطالب خوبی پیدا کنید.کتابهای دانشگاهی در این زمینه ها هم بد نیستند. 
اگر سوالی داشتید مطرح کنید, شاید بتونم با علم اندکم جوابتون رو بدم. موفق باشید.

----------


## amin32

> الان کی تحلیلگر لغوی رو می نویسه؟ من بنویسم؟ دقیقا چی ... ؟


همون طور که گفتم شما روی تحلیلگر نحوی تمرکز کنید و سعی کنید بیشتر درکش کنید تا وقتمون تلف نشه. من دارم روی تحلیلگر لغوی کار میکنم.

----------


## amin32

فقط یه خواهشی از تمامی دوستان دارم.

کدهایی که از این به بعد اینجا قرار میگیره فقط جنبه آموزشی داره و برای انجام این پروژه هست. لطفآ از اونها بدون ذکر منبع (آدرس تاپیک) استفاده نشه.

----------


## amin32

این هم تحلیلگر لغوی زبانمون

باز هم تکرار میکنم که این کدها فقط برای استفاده در این پروژه نوشته میشن و اینجا قرار میگیرند.
در ضمن به خاطر عجله در تعیین ساختار زبانمون, یادمون رفت که نوع بولی رو مشخص کنیم. که من نوع bool و مقادریر true , false رو به زبانمون اضافه کردم.

این هم پروتکل های تحلیلگر لغوی با تحلیلگر نحوی:

شناسه: id=1 
کلمه کلیدی: KeyW = 2 
علامت ":" : COLON = 3
علامت "+": Add_OPR = 4
علامت "-": SUB_OPR = 5 
علامت "*": MUL_OPR = 6
علامت "/": DIV_OPR = 7
علامت "=": ASSIGN = 8
علامت "<": GREATER = 9
علامت ">": LESS = 10
علامت "=<": GreatEqual = 11
علامت "=>": LessEqual = 12
علامت "<>" : NotEqual = 13
علامت ")": PARENTHESIS_O = 14
علامت "(": PARENTHESIS_C = 15
خط جدید : NewLine = 16
داده رشته ای: STRING_ = 17
داده کاراکتر: CHAR_ = 18
داده صحیح: INTIGER_ = 19
داده اعشاری: FLOAT_ = 20
لغت اشتباه: Error = 21

لینک اصلاح شد !

Lexical Analyzer.zip

----------


## IamOverlord

عالیه!  :چشمک: 
مرحله ی بعد چیه؟ الان باید بریم سراغ تحلیگر نحوی یا کاری هست که باید قبلش بکنیم؟

----------


## IamOverlord

اگه یه لغت اشتباه بدیم Error = 21 می ده اما اگه یه Symbol اشتباه مثل , بدیم؟

----------


## amin32

> اگه یه لغت اشتباه بدیم Error = 21 می ده اما اگه یه Symbol اشتباه مثل , بدیم؟


اتفاقآ داشتم حلش میکردم.

----------


## IamOverlord

اگه درست متوجه شده باشم، بهتره دوباره داخل Case Is = 20 یه Select Case دیگه بذاری...

----------


## amin32

لینک اصلاح شد.




> اگه درست متوجه شده باشم، بهتره دوباره داخل Case Is = 20 یه Select Case دیگه بذاری...


چرا؟؟؟

----------


## IamOverlord

> چرا؟؟؟


این طوری فکر کنم مشکل حل می شه:

    Case Is = 20
        Select Case temp
            Case temp = vbCr Or temp = vbLf
                CurrentLetter = CurrentLetter + 2
                CreateNewWord NewLine, CurrentWord
                CurrentWord = ""
                state = 1
            Case " "
                CurrentLetter = CurrentLetter + 1
                CurrentWord = ""
                state = 1
            Case ""
                Exit Do
            Case Else
                CreateNewWord Error, temp
                CurrentLetter = CurrentLetter + 1
                CurrentWord = ""
                state = 1
        End Select

----------


## IamOverlord

> لینک اصلاح شد.


یه مشکلی همچنان هست:
اگه یه Symbol اشتباه بدیم تشخیص می ده و Error = 21 می ده ولی برای بعدی ها هم همین طور 21 رو می نویسه.

----------


## amin32

> Case Is = 20
>         Select Case temp
>             Case temp = vbCr Or temp = vbLf
>                 CurrentLetter = CurrentLetter + 2
>                 CreateNewWord NewLine, CurrentWord
>                 CurrentWord = ""
>                 state = 1
>             Case " "
>                 CurrentLetter = CurrentLetter + 1
> ...


ببخشید ولی من اصلآ متوجه منظورت نشدم! این کد چه  قابلیتی رو اضافه میکنه؟

----------


## IamOverlord

این رو به جای کد قبلی Case Is = 20 می ذاریم تا اون مشکل رو حل بشه. Symbol غلط رو همراه با Error 21 گزارش می ده و بعد به کارش ادامه می ده ...

----------


## amin32

اینم حل شد. فقط یک خط کد کم نوشته بودم!!!!!!

state=1

این خط حالت فعلی dfa رو به حالت شروع میبره که یادم رفته بود بنویسم.

----------


## IamOverlord

یه اشتباهی کردم؛ باید به جای

            Case temp = vbCr Or temp = vbLf
                CurrentLetter = CurrentLetter + 2
                CreateNewWord NewLine, CurrentWord
                CurrentWord = ""
                state = 1

نوشت :

            Case vbCr
                CurrentLetter = CurrentLetter + 2
                CreateNewWord NewLine, CurrentWord
                CurrentWord = ""
                state = 1
            Case vbLf
                CurrentLetter = CurrentLetter + 2
                CreateNewWord NewLine, CurrentWord
                CurrentWord = ""
                state = 1

----------


## amin32

> ضمنا یه اشتباهی هم هست. باید به جای
> 
>             Case temp = vbCr Or temp = vbLf
>                 CurrentLetter = CurrentLetter + 2
>                 CreateNewWord NewLine, CurrentWord
>                 CurrentWord = ""
>                 state = 1
> 
> نوشت :
> ...


اشتباه میکنی! کاربر با زدن اینتر در واقع این دو کاراکتر رو ایجاد میکنه. ما هم با دیدن یکی از این دو کاراکتر دو کاراکتر رو رد میدیم. و در واقع فقط اون دو رو یک کاراکتر خط جدید تشخیص میدیم.

----------


## IamOverlord

> اشتباه میکنی! کاربر با زدن اینتر در واقع این دو کاراکتر رو ایجاد میکنه. ما هم با دیدن یکی از این دو کاراکتر دو کاراکتر رو رد میدیم. و در واقع فقط اون دو رو یک کاراکتر خط جدید تشخیص میدیم.


فهمیدم منظورتون رو اشتباه از من بود که Case temp = vbCr Or temp = vbLf رو نوشتم چون اجرا نمی شه، باید به جاش یه چیز دیگه نوشته می شد که حل شد.

بابت زحمتی که کشیدید ممنون!  :قلب: 

مرحله ی بعد چی هست؟

----------


## amin32

مرحله بعد تحلیلگر نحوی ............

----------


## maktoom

سلام
تحلیلگر لغوی اینجا تموم شد؟
من ویژوال بیسیک رو خیلی کم بلدم(در حد کار با بسکام) بنابراین نمی تونم اینجا اظهار نظری بکنم. اما قبلا قسمت ثابتهای عددی رو با سی نوشتم.
کدش حدود 700 خط شد.
دقت کنید فقط ثابتهای عددی. حتی ثابتهای رشته ای رو هم ننوشتم فقط ثابت های عددی.
پیش بینی من برای کل تحلیلگر لغوی البته در زبان سی چیزی حدود 2000 خط کده.
که البته با ترتیبی که بنده نوشتم باقی کار فقط اضافه کردن کیس های بیشتره.
اما یه چیزی اینجا مشکل زا میشه و اونم شبیه بودن بعضی ساختارهاست. که باید شروط داخل هر case از پس تشخیصشون بربیاد.
مثال واضحش تشخیص یک شناسه از مثلا کلمه کلیدیه while هستش. یا مثلا پیمایش دیاگرامهایی که بزرگتر هستن.
اینا نکاتیه که جدا در پیاده سازی اذیت می کنه. شاید برای یک کیس که محل تقاطع چنتا دیاگرام هست 6 تا 7 شرط بررسی شباهت برای تعیین شروع از دیاگرام درست باشه.
خروجی این مرحله باتوجه به منابعی که دیدم به این شکله:
یک جدول که دارای یک فیلد id و یک فیلد برای خود شناسه و یک فیلد برای نوع شناسهو یک فیلد دیگه برای محتوای اونه. فیلد دیگه ای هم تعبیه میشه تا تعیین کنه این شناسه از کلمات کلیدیه زبانه یانه.
وقتی این جدول که به اصطلاح symbol table می نامنش پر شد. از روی اون توکن ها رو می سازن. توکن مثلا برای عملگر = به این صورته:
<OP,=>
و برای یک شناسه مثل x25 که در ردیف مثلا هشتم ذخیره شده به این شکل:
<id8,x25>
و برای یک رشته ورودی شروع می کنن شناسه ها و کلمات کلیدی رو از جدول تطبیق می دن(درصورت موجود نبودن اضافه می کنن) و بصورت توکنها نمایش می دن.
 از روی توکن ها میشه یه درخت تجزیه ابتدایی رسم کرد.

----------


## IamOverlord

فعلا این تحلیلگر لغویمون کار داره...
اگه یه رشته مثل "ABCDE" بدی بهش به صورت "abcde" تشخیص می ده، یعنی همه ی حروف رو کوچیک می کنه.

----------


## Hossenbor

خوب پروژه به کجا رسید منم دارم پروژه مو شروع می کنم از زبان اسمبلی و ساختن سیستم عامل شروع می کنم

----------


## Hossenbor

داداشمون راست میگه زمان اینجا خیلی ارزش داره اگه بجای نوشتن اینجا چت می کردیم بهتر بود زمان کمتری گرفته میشد به هر حال ایدی نیمبازم ...m.a.j.n.o.n... یاهو هم ایدی دارم اونم همین نام کاربریمه که زیاد باهاش ان نمیشم اگه تونستی بیایی نیمباز یک روم بساز اسمشم همینجا بذار تا که بیام همونجا مزاحمت میشم

----------


## amin32

> فعلا این تحلیلگر لغویمون کار داره...
> اگه یه رشته مثل "ABCDE" بدی بهش به صورت "abcde" تشخیص می ده، یعنی همه ی حروف رو کوچیک می کنه.


چرا اینقدر سخت میگیری!!!
اینو من عمدآ برای ساده شدن اینطور درنظر گرفته بودم.(البته موقتآ). چیز مهمی نیست. کافی بود lcase رو حذف کنی و "A" و "Z" رو هم با temp مقایسه کنی. هرچند خودم اینکارو کردم و لینک رو هم اصلاح کردم. میتونی دانلود کنی. من قصد داشتم این موارد رو یه دفعه تو مرحله Optimization انجام بدم.

----------


## amin32

> سلام
> تحلیلگر لغوی اینجا تموم شد؟
> من ویژوال بیسیک رو خیلی کم بلدم(در حد کار با بسکام) بنابراین نمی تونم اینجا اظهار نظری بکنم. اما قبلا قسمت ثابتهای عددی رو با سی نوشتم.
> کدش حدود 700 خط شد.
> دقت کنید فقط ثابتهای عددی. حتی ثابتهای رشته ای رو هم ننوشتم فقط ثابت های عددی.
> پیش بینی من برای کل تحلیلگر لغوی البته در زبان سی چیزی حدود 2000 خط کده.


ببینید عبارت با قاعده ثوابت عددی اینه:

*[9-0][9-0]

درسته؟
کاملآ مشخصه که dfa مربوطه باید دو حالت داشته باشه, یعنی دو تا case . شما برای ایجاد این دو حالت 700 خط کد نوشتید!!!!!
در کل اصلآ متوجه منظورتون نشدم. الان به نظر شما عملکرد این تحلیلگر لغوی ناقصه؟ عیبی داره؟ اینکه با دستورات کمتر از انتظارتون نوشته شده رو نقصان میدونید؟

----------


## amin32

باید زودتر تصمیم بگیریم که از چه روشی برای پیاده سازی تحلیلگر نحوی استفاده کنیم.در این تحلیلگر ما بحث تجزیه کننده رو داریم. .به نظر من ساده ترین نوعش تجزیه کننده پیشگو هست که واقعآ سادست. اما مشکل بزرگش اینه که بازگشتیه و در نتیجه اصلآ بهینه نیست.
اگه تصمیم باشه از الگوریتمهای بهتر و پیچیده تر استفاده بشه, من ترجیه میدم بهترینش رو انتخاب کنیم. حتی اگه خیلی پیچیده باشه.

----------


## IamOverlord

در کل کدهای C نسبتا حجیم هست، طبیعیه ...

----------


## IamOverlord

> چرا اینقدر سخت میگیری!!!


سخت نمی گیرم آخه اگه رشته ی "Hello World" رو بدیم خروجی "hello world" می شه..

----------


## amin32

> در کل کدهای C نسبتا حجیم هست، طبیعیه ...


در ساختار های اصلی , کدهای نوشته شده با C فرق آنچنانی با vb نداره (از نظر حجم کد) . فقط در مسائلی مثل کار با  ورودی/خروجی کدها کمی اضافه میشن.

----------


## amin32

> سخت نمی گیرم آخه اگه رشته ی "Hello World" رو بدیم خروجی "hello world" می شه..


الان مگه باز هم این مشکل وجود داره؟؟
در کل من برنامه رو طوری نوشتم که بشه هر تغییری رو به راحتی ایجاد کرد. نگران این تحلیلگر نباش.
همونطور که گفتم یه سری تغییرات رو باید بزاریم برای مرحله Optimization.مثلآ من از عمد فعلآ متغیر WordCount رو integer در نظر گرفتم. این یعنی تعداد لغت های کشف شده نمیتونن از 32767 بیشتر باشن! برای حلش کافیه نوع متغیر رو long در نظر بگیری. و من حتمآ دلیلی داشتم برای این کار.
ولی باز میگم به این مسائل جزئی فکر نکن.

----------


## IamOverlord

> الان مگه باز هم این مشکل وجود داره؟؟


دوباره دانلود کرذم.
اینو ببینید:

----------


## amin32

الان که یکم فکر کردم باید هر کلمه کلیدی رو هم یک نوع لغت در نظر بگیریم. این قابلیت رو هم اضافه کردم.

Lexical Analyzer.zip

----------


## amin32

> دوباره دانلود کرذم.
> اینو ببینید:


اون هم حل شد. یادم رفته بود lcase مربوط به لغت رشته ای رو پاک کنم. تمام مشکلات مربوط به کوچک شدن حروف حل شد. دوباره فایل رو از پست قبل دانلود کن.

----------


## amin32

من هنوز فکر میکنم بهتر باشه دو تا دستور ساده برای خواندن و نوشتن در خط فرمان به ساختار زبان اضافه بشه.

----------


## IamOverlord

چه دستوراتی؟
ولی این طوری مجبور می شیم هزار تا دستور دیگه هم برای تغییر رنگ و پاک کردن صفحه و ... بنویسیم. من نمی دونم می خوایم تو مایه های BASIC عمل کنیم یا مثلا C. من که نظرم اینه تو فایل های سرآیند دستورات رو تعریف کنه.

----------


## amin32

نه فقط منظورم در مورد ورودی خروجی بود. بعد میتونیم در مرحله توسعه همه موارد رو به شکل کتابخانه در بیاریم.

----------


## amin32

ببین, من منظورم اینه که دو تا دستور مثلآ read و write داشته باشیم تا وقتی که هنوز برنامه رو توسعه ندادیم. برنامه نویس بتونه یه برنامه محاسباتی ساده مثل ماشین حساب بنویسه! حمایت کاپایلر از کتابخانه یکم کار ساختش رو پیچیده میکنه. به نظرم بهتره اون رو به مرحله توسعه موکول کنیم.

----------


## maktoom

سلام دوستان

من برنامم رو از روی این دیاگرام نوشتم.
Loghavi.Adad.jpg

توضیح برای other اینکه یعنی اسکنر یک کاراکتر اضافه خونده و باید برگرده و تا قبل از اون رو برای اون دیاگرام پذیرش کنه.

----------


## maktoom

شاید پیاده سازی تک تک دیاگرامهای ثابتهای عدی به تنهایی مجموع کدشون خیلی کمتر از تعداد کدیه که گفتم. 
دلیل حجیم شدن مجموع دیاگرامها در قالب یک برنامه شرطهای خاصیه که باید تعبیه بشه تا مرزهای تفکیک دیاگرامها رو مشخص کنه.
همچنین کدهای زیادی اضافه میشن برای اینکه اگه کاراکتر ورودی برابر یک کاراکتر خاص بود حالا باید به کدوم وضعیت بره. که برای یک تک دیاگرام فقط اعلام شکست کافی بود.

----------


## maktoom

راستی خیلی خوشحال کنندس با دو تا کیس ثابتهای عددی رو نوشتید. حالا اگه امکان داره 7-8 خط دیگه اضافه کنید تا دیگر ثابتهای عددی رو هم بپذیره.

----------


## amin32

> ببینید عبارت با قاعده ثوابت عددی اینه:
> 
> *[9-0][9-0]
> 
> درسته؟



من منظورم از این فقط اعداد صحیح بود که به اشتباه ثوابت عددی رو بیان کردم. در ضمن حالتهای -/+ در dfa ای که قرار دادید باید حذف بشن. چون این کاملآ وظیفه تحلیلگر معناییه که تشخیص بده که علامت "-" برای تفریق به کار رفته یا نمایش منفی. برای تشخیص درستی ساختار هم باید گرامرهای تفریق و منفی کردن رو به تحلیلگر نحوی اضافه کنید. من خیلی علاقه دارم دوستان بیان اینجا و ایرادهای کار رو به ما بگن. اما لطفآ واضحتر بیان کنید دقیقآ چه لغتی رو باید تحلیلگر بشناسه ولی تحلیلگر ما نمیشناسه. متشکر

----------


## maktoom

این دیاگرام و دیگر دیاگرام ها رو می تونید در کتاب اقای اهو به ترجمه دکتر دلداری ببینید. صفحه 108
در اونجا مثبت و منفی ابتدای عدد رو در نظر نگرفته. اما برای توان ده در نماد علمی در نظر گرفته که اینهم دلیلش مشخصه.
البته اونجا دیاگرام در پاسکال رو بیان کرده و مقدار کمی تفاوت داره.

در صفحه 177 اشاره به درنظر گرفتن - قبل از id شده. (مربوط به تحلیلگر نحوی)

درمورد اینکه چه چیزهایی رو نمی پذیره. فقط وقتی میشه کاملا درست بررسیش کرد که دیاگرامهایی روکه از روی اون برنامه رو نوشتید بیارید.
ممکنه شما جور دیگه ای بخواید هرچیزی رو پیاده سازی کنید. بنابراین باید دیاگرام هر کدوم رو بیارید.
 تا بشه فهمید هرکدوم از کیسها برای کدوم وضعیت در نظر گرفته شدن و ورودی و خروجی های هر وضعیت هم درست درنظر گرفته شدن یا نه.

بیاید یه لحظه فکر کنیم به همین شکل کار به اتمام برسه و شما یه زبان جدید با یه کامپایلر دارید.(جدا نامحتمل نیست)
به اولین استادی که نشون بدید بسرعت نواقص سرسام آوری رو ازش میگیره و ناکارآمدی اون رو نشون میده.

آکادمیک کار کردن ، دیاگرام داشتن، سر حوصله کار کردن، با دقت فراوان کار کردن و... اینا باعث میشه نواقصی که قراره کس دیگه نشونمون بده خودمون همینجا پیداش کنیم و حلش کنیم.

وقتی میگید بریم سراغ تحلیلگر نحوی یه لحظه این اومد تو ذهنم که همه دیاگرامهای ثابتهای عددی و غیر عددی(رشته ای) و علائم خاص زبان و کلمات کلیدی زبان و... رو دارید و پیاده سازیشون رو هم دارید.
اما وقتی استناد به دو تا کیس کردید جدا تو فکر رفتم.

همین الان که دارم اینا رو می نویسم یه بار دیگه بعضی مباحث رو از کتاب کامپایلرها(اصول، طراحی و روش ها) از آلفرد وی.اهو/راوی سدی/جفری دی.اولمن به ترجمه دکتر حسین دلداری/مهندس محمد مهدی سالخورده حقیقی مطالعه کردم تا بتونم مباحث مطمئنی برای پیشبرد صحیح کار ارائه بدم. من بیشتر دوست دارم استفاده درست از دانش ایجاد یک کامپایلر رو در اینجا ببینم تا صرفا یه خروجی. البته وسواس بی جهت کار رو سرد می کنه. ولی عجله هم خرابی ببار میاره.

----------


## amin32

> اما برای توان ده در نماد علمی در نظر گرفته که اینهم دلیلش مشخصه.


این رو نمیشه یک عیب دونست. این از مواردیه که من برای ساده تر شدن قضیه فعلآ ازش صرفه نظر کردم.




> آکادمیک کار کردن ، دیاگرام داشتن، سر حوصله کار کردن، با دقت فراوان کار کردن و... اینا باعث میشه نواقصی که قراره کس دیگه نشونمون بده خودمون همینجا پیداش کنیم و حلش کنیم.


نمیدونم شاید حجم کم کدها باعث شده اینطور فکر کنید که من این موارد رو رعایت نکردم و به این اصول پایبند نبودم.
سعی میکنم DFA زبان رو به شکل کامپیوتری رسم کنم.

----------


## amin32

اینم از DFA اولیه لغات زبان که البته فکر میکنم بعدش خود برنامه یکی دو تا تغییر خیلی کوچیک داشت.
یادآوری اینکه همونطور که میدونید نقطه های قسمت رشته , یعنی هر کاراکتری غیر از کاراکتر خط جدید.

DFA.jpg

فکر میکنم واقعآ کسی نباشه که بتونه همکاری کنه و علاقه چندانی به این موضوع جالب از کسی دیده نمیشه. یکم وضعیت اینجا ناامید کنندست.

----------


## IamOverlord

> فکر میکنم واقعآ کسی نباشه که بتونه همکاری کنه و علاقه چندانی از کسی دیده نمیشه. یکم وضعیت اینجا ناامید کنندست.


سلام دوست عزیز  :چشمک: 
متاسفانه در مسائل تئوریک شما از من بیش تر می دونید! :دی
یه موقع فکر نکنید بحث رو ول کردم، اما مثل این که الان نوبت من نیست... در این تحلیلگر شما ها اطلاعات بیش تری فکر می کنم داشته باشید.
اما در مورد کد زدن منتظرم تا مشخص بشه چی بنویسم.

اما در کل حق دارید تاپیک خیلی خلوته با این که آمار بازدید کم نیست... امیدوارم بقیه ی دوستان در هر جا که ممکنه اظهار نظر کنند و کمک کنند در کدنویسی.

----------


## maktoom

دیاگرام از سه جنبه ایراد داره(بریم به سمت همکاری):
اول اینکه وضعیت other براش در نظر گرفته نشده. مشکلی بوجود میاد مثلا برای این عبارت :
x=2;
نمی تونه x رو بعنوان یه شناسه بشناسه.چون نشانگر انتهای توکن که other باشه در برنامه تعبیه نشده.(اسکنر با رسیدن به = نمی فهمه باید چکار کنه یعنی کار درست رو انجام نمیده. کار درست اینه که به مساوی دست نزنه اگه خونده برگرده تا در گام بعد بفهمه برای = از کدوم دیاگرامش باید استفاده کنه.) همچنین عدد 2 هم بخاطر قرار گرفتن ; قابل شناسایی نیست.(دلیل وجود other نامتنهای بودن طول رشته پذیرش اون دیاگرامه که با یه کاراکتر دیگه که مال یه توکن دیگس به اسکنر میفهمونیم که کار تو در این دیاگرام تموم شده و تا قبل از کاراکتر نامربوط رو پذیرش کن)
برعکس اون برای عملگر بزرگتر مساوی یا کوچکتر مساوی یا ++ یا -- یا== بعد از آخرین توکن متوقع کاراکتر دیگه ای نیستیم پس چون یک رشته متناهی داریم که انتهاش معلومه به محض رسیدن به انتهای رشته پذیرش می کنیم و other اینجا نداریم. 
دوم اینکه بجهت سهولت کار و کم شدن حجم کد بهتره وضعیتهای مشابه رو در یک دیاگرام در نظر بگیریم:

Scan0031.JPG

ایراد سوم اینه که وضعیتها شماره گذاری نشدن. که به این معناست که اولویت بررسی وضعیتها در نظر گرفته نشده. در شرایطی که یک دیاگرام کم استفاده است یا طول کمتری داره اگه اولویت رو به اون بدیم تشخیص توکن ها قطعا اشتباه خواهد بود.
از اینکه اینطور زحمت کشیدید و به مطالب گفته شده اهمیت دادید خوشحالم.
 بهرحال همه در حال یادگرفتن هستیم.
از دوستانی که از این صفحه دیدن می کنن می خوام مطالب صفحات این تاپیک رو بخونن. مطالب با ارزشی گفته شده.
همچنین کتب معرفی شده در این تاپیک از هرکدوم که شروع بشه راهی به سمت فهم بهتر مطالب این تاپیکه و شما هم مطمئنا می تونید مطلبی رو در همکاری با این کار مهم بیان کنید که سودمند باشه.

----------


## amin32

> دیاگرام از سه جنبه ایراد داره(بریم به سمت همکاری):
> اول اینکه وضعیت other براش در نظر گرفته نشده. مشکلی بوجود میاد مثلا برای این عبارت :
> x=2;
> نمی تونه x رو بعنوان یه شناسه بشناسه.چون نشانگر انتهای توکن که other باشه در برنامه تعبیه نشده.(اسکنر با رسیدن به = نمی فهمه باید چکار کنه یعنی کار درست رو انجام نمیده. کار درست اینه که به مساوی دست نزنه اگه خونده برگرده تا در گام بعد بفهمه برای = از کدوم دیاگرامش باید استفاده کنه.) همچنین عدد 2 هم بخاطر قرار گرفتن ; قابل شناسایی نیست.(دلیل وجود other نامتنهای بودن طول رشته پذیرش اون دیاگرامه که با یه کاراکتر دیگه که مال یه توکن دیگس به اسکنر میفهمونیم که کار تو در این دیاگرام تموم شده و تا قبل از کاراکتر نامربوط رو پذیرش کن)
> برعکس اون برای عملگر بزرگتر مساوی یا کوچکتر مساوی یا ++ یا -- یا== بعد از آخرین توکن متوقع کاراکتر دیگه ای نیستیم پس چون یک رشته متناهی داریم که انتهاش معلومه به محض رسیدن به انتهای رشته پذیرش می کنیم و other اینجا نداریم. 
> دوم اینکه بجهت سهولت کار و کم شدن حجم کد بهتره وضعیتهای مشابه رو در یک دیاگرام در نظر بگیریم:
> 
> Scan0031.JPG
> 
> ...


 [_a-zA-Z0-9^] یعنی همون other و در زبانهای با قاعده یعنی هر لغتی غیر از _a-zA-Z0-9 . فکر میکردم اینو بدونید. من برای مشخص شدن کامل مساله از اون استفاده کردم.میتونید مراجع رو مطالعه کنید.

در مورد ایراد دوم باید عرض کنم این همون قسمتی بود که در برنامه تغییر کرد. میتونید در کدش هم چک کنید. به همین خاطر بود که گفتم یک تغییر کوچیک داشته. در ضمن مشکلش  زیاد شدن کد نبود. اگر خوب دقت کنید با این حالت به جای DFA  ما یک NFA داشتیم! و به همین دلیل همونطور که گفتم این قسمت در برنامه تغییر کرد.

در مورد شماره گذاری حالتهاهم فکر میکنم هر کسی بدونه که حالتهای DFA باید شماره گذاری بشه .و این DFA ای که روی کاغذ رسم شده و الان روبروی من قرار داره, شماره گذاری شده. من قصد داشتم در پایان رسم کامپیوتری DFA , شماره ها رو قرار بدم که فراموش کردم. فکر میکنم اینو هر کسی میتونست حدس بزنه. در کل رسم کامپیوتری DFA در برنامه کاری من قرار نداشت و قصد داشتم همون DFA روی کاغذ رو پیاده سازی کنم.

به نظر من در حال حاضر بهترین راه برای عیب یابی تحلیلگر , تست خود برنامه هست . چون اگه DFA هم درست باشه , ممکنه برنامه اون رو خوب پیاده سازی نکرده باشه. به راحتی میتونید با دادن ورودی های مختلف  خروجی تحلیلگر رو چک کنید. در ضمن همونطور که متوجه شدید پروتکلها هم تغییر کردند. میتونید پروتکلها رو در داده شمارشی WordType ببینید.

----------


## amin32

> سلام دوست عزیز 
> متاسفانه در مسائل تئوریک شما از من بیش تر می دونید! :دی
> یه موقع فکر نکنید بحث رو ول کردم، اما مثل این که الان نوبت من نیست... در این تحلیلگر شما ها اطلاعات بیش تری فکر می کنم داشته باشید.
> اما در مورد کد زدن منتظرم تا مشخص بشه چی بنویسم.
> 
> اما در کل حق دارید تاپیک خیلی خلوته با این که آمار بازدید کم نیست... امیدوارم بقیه ی دوستان در هر جا که ممکنه اظهار نظر کنند و کمک کنند در کدنویسی.


به خاطر اینکه گفتید به اسمبلر مسلط هستید , فکر میکنم قابلیت شما بیشتر در BackEnd باشه . و چون مسائل FrontEnd تئوریک تر هستند , باعث شده که زیاد به شکل عملی در موضوع شرکت نکنید. من اینو درک میکنم. اما فکر میکنم با محدودیت زمانی که من دارم, بهتر باشه دوستانی که هم با تحلیلگرها و هم با زبان پیاده ساز آشنایی دارن , بیشتر همکاری کنند. وگرنه باید منتظر یه وقفه طولانی باشیم ( شاید تا تعطیلات تابستان!! )

ببینید الان به غیر از تحلیلگر لغوی , برای جلوبندی سه تا فاز مهم دیگه باقی مونده:

1- تحلیلگر نحوی

2- تحلیلگر معنایی

3- تولید کننده کد میانی ( که توجه من روی کد سه آدرسه هست )

----------


## maktoom

وقتی در یک گفتگو و همکاری کار به چنین مقطعی میرسه... دقیقتر بگم به اصطکاک میرسه. و هر گونه نقد به غرضورزی تعبیر میشه. و تلاش گروه داره فدای این حرفای پوچ میشه. و اثبات درست بودن یه چیز غلط ... درصورتیکه میشه پذیرای اون بود و حتی کار رو تقسیم کرد. و این رو متوجه نشیم که کار گروهی هر نقدی بهش وارد بشه مسئولیتش به گردن تک تک اعضای اون پروژست و لزومی نداره کسی خودش رو بارکش این مسئولیت و هدف اون نقد بدونه. این نشون میده فرهنگ اپن سورس، فرهنگ کار تیمی هنوز در این تاپیک کمبود داره.
من تمامی نقص هام و عیبهام و کمبودهام رو می پذیرم.
و همچنین تمامی سوادم و تمامی دانشم رو و تمامی وقتم رو صرف این تاپیک کردم. تا در انتها پیش خودم شرمنده نباشم که تلاش یه عده رو تحت تاثیر مفاهیم غلط بیان شده توسط خودم بذرام. با وجدانم سعی کردم. نقد کردم و سعی در ایجاد یک معیار برای تشخیص میزان انحراف داشتم. هدفم براورده نشد.
دیگه در این تاپیک پستی نخواهم گذاشت و دوستان می تونن به نحوی که پیش از این در حال حرکت بودن با سرعت و بدون اصطکاک بکارشون ادامه بدن.
از خودم می پرسم چرا باید وقتم رو در مقطعی که درگیر چندین پروژه و کار هستم باید صرف اصطکاکی بکنم که نتیجش فقط اتلافه انرژیه؟ و وقتی دوستان به این حد از اعتماد بنفس در بیان نظر شخصیشون و اعمال اون برروی عملکرد گروه هستن چه احتیاجی به وقت شبانه ایه که در این وقت نداشته بذارم روی این پروژه؟ 
بهرحال من هم مثه شما و حداقل اغلب شما موقعی که این درس رو گرفته بودم با نمره کامل  گذروندم گرچه همون روز امتحان ریزپردازنده ها(8051) هم داشتم که اون رو هم با نمره کامل گذروندم. گفتم شاید سوادی که کسب کردم و عمقی که در این درس زدم و با تدریسی که در این درس برای کنکور برعهده گرفتم بتونم از طرق مختلف با افراد زبردست مرتبط بشم و از اونها در این پروژه یاری بگیرم. قصدی بجز یادگرفتن نداشتم و از اینکه به سرعت شما لطمه زدم متاسفم.
دیگه به این تاپیک سر نخواهم زد و امیدوارم شما بتونید با سرعت پیشین و حتی سریعتر بکارتون ادامه بدید.
منم با دیگر تاپیکها خودم رو مشغول می کنم و سعی به یادگرفتن مباحث طرح شده در اونجا خواهم کرد.
موفق و پیروز باشید.

خدانگهدار

----------


## amin32

> وقتی در یک گفتگو و همکاری کار به چنین مقطعی میرسه... دقیقتر بگم به اصطکاک میرسه. و هر گونه نقد به غرضورزی تعبیر میشه. و تلاش گروه داره فدای این حرفای پوچ میشه. و اثبات درست بودن یه چیز غلط ... درصورتیکه میشه پذیرای اون بود و حتی کار رو تقسیم کرد. و این رو متوجه نشیم که کار گروهی هر نقدی بهش وارد بشه مسئولیتش به گردن تک تک اعضای اون پروژست و لزومی نداره کسی خودش رو بارکش این مسئولیت و هدف اون نقد بدونه. این نشون میده فرهنگ اپن سورس، فرهنگ کار تیمی هنوز در این تاپیک کمبود داره.
> من تمامی نقص هام و عیبهام و کمبودهام رو می پذیرم.
> و همچنین تمامی سوادم و تمامی دانشم رو و تمامی وقتم رو صرف این تاپیک کردم. تا در انتها پیش خودم شرمنده نباشم که تلاش یه عده رو تحت تاثیر مفاهیم غلط بیان شده توسط خودم بذرام. با وجدانم سعی کردم. نقد کردم و سعی در ایجاد یک معیار برای تشخیص میزان انحراف داشتم. هدفم براورده نشد.
> دیگه در این تاپیک پستی نخواهم گذاشت و دوستان می تونن به نحوی که پیش از این در حال حرکت بودن با سرعت و بدون اصطکاک بکارشون ادامه بدن.
> از خودم می پرسم چرا باید وقتم رو در مقطعی که درگیر چندین پروژه و کار هستم باید صرف اصطکاکی بکنم که نتیجش فقط اتلافه انرژیه؟ و وقتی دوستان به این حد از اعتماد بنفس در بیان نظر شخصیشون و اعمال اون برروی عملکرد گروه هستن چه احتیاجی به وقت شبانه ایه که در این وقت نداشته بذارم روی این پروژه؟ 
> بهرحال من هم مثه شما و حداقل اغلب شما موقعی که این درس رو گرفته بودم با نمره کامل  گذروندم گرچه همون روز امتحان ریزپردازنده ها(8051) هم داشتم که اون رو هم با نمره کامل گذروندم. گفتم شاید سوادی که کسب کردم و عمقی که در این درس زدم و با تدریسی که در این درس برای کنکور برعهده گرفتم بتونم از طرق مختلف با افراد زبردست مرتبط بشم و از اونها در این پروژه یاری بگیرم. قصدی بجز یادگرفتن نداشتم و از اینکه به سرعت شما لطمه زدم متاسفم.
> دیگه به این تاپیک سر نخواهم زد و امیدوارم شما بتونید با سرعت پیشین و حتی سریعتر بکارتون ادامه بدید.
> منم با دیگر تاپیکها خودم رو مشغول می کنم و سعی به یادگرفتن مباحث طرح شده در اونجا خواهم کرد.
> موفق و پیروز باشید.
> ...


دوست عزیز از حرفهای من ناراحت نباشید.خواهش میکنم یکبار دیگه انتقادهای خودتون و جوابهای من به انتقادهاتون رو بخونید.از من چه انتظاری داشتید.برای مواردی که درست بودن و مواردی که به خاطر فراموشی جا مونده بود میگفتم اینها رو نمیدونستم!!! من هیچ ادعایی ندارم. این رو هم میگم که نمراتم چنگی به دل نمیزنه و کلآ زیاد به نمره و دانشگاه فکر نمیکردم( لااقل تا همین چند وقت) و فقط از سر علاقه مباحثی رو که دوست داشتم میخوندم. در علم شما هم شکی ندارم. قبول دارم شاید یکم لحنم تند بود ولی خودتون نگاه کنید به انتقادهایی که تا الان کردید. قطعآ هدفتون کمک به پروژه بود ولی فکر میکنم یک کمی نابجا بود. فقط خودتون رو بگذارید جای من وقتی دارید در مورد ساختار کلی زبان بحث میکنید و اون رو مشخص میکنید, من بیام و بگم چرا از الان به فکر گرامرهای مبهم و راهبرد برخورد با خطا نیستید. کلآ برای من رفتارهای بد انسانها ( ریاست طلبی, حسادت و....) در فضای مجازی خیلی مضحک به نظر میاد. من از شما ناراحت نیستم و امیدوارم شما هم از من ناراحت نباشید. موفق باشید.

----------


## IamOverlord

باز خدا رو شکر شما چهار تا نمره ی دانشگاهی دارید، من که هنوز...! :گیج: 

ببخشید دوستان،
اگه به نظرتون کم کاری از من هست، به خاطر این که نمی خوام نظر چرت و پرت بدم،
اصلا اول اول هدفم این بود که یه برنامه بنویسم که توش به جای چیزایی که می نویسم چند خط کد Assembly بذاره که آدم این قدر از کدهای تکراری عذاب نکشه،
بعد ... داستان به ساخت کامپایلر رسید،
خوب گفتم چه بهتره که اصولی باشه و از کسایی که علمشو دارن کمک بگیرم بعد اون قسمت تولید کدهای Assembly رو بنویسم،
هنوز هم سر حرفم هستم و در قسمت آخر هر کمکی از دستم بر می آد می کنم.
قبول دارم که این قسمت ها پیچیده تره، طبیعیه که یه کم کند پیش رفته، باز حداقل بحث پیش بره و به نتیجه برسه بهتره.
اگه حاصل این 20 30 صفحه ی تاپیک یه زبان با 2 تا دستور باشه، بهتر از اینه که هیچی نباشه،
نمی دونم چه طلسمیه که پروژهای Open Source این فروم ها همه یه بلایی سرشون می آد!
نباید بذاریم این جا هم مثل بقیه ... .

دوباره بحث رو ادامه بدیم، از صحبت تند (البته بدون توهین و تمسخر و...) نترسیم یا نارخت نشیم، چون بحث علمیه و بحث و مشاجره در علم سازنده است. بی رو دربایستی بحث رو ادامه می دیم...

----------


## amin32

خب ساخت تحلیلگر لغوی یک الگوریتم تقریبآ مشخص داره. ( پیاده سازی DFA ) ولی مشکل از اینجا به بعد شروع میشه. یعنی اینکه برای تحلیلگر نحوی و تجزیه کننده اون از چه الگوریتمی استفاده کنیم. متآسفانه یا خوشبختانه الگوریتم های زیادی برای این تحلیلگر وجود داره. تآسف به این خاطره که تصمیم گیری در مورد اینکه کدوم الگوریتم استفاده بشه یکم مشکله. معایب و مزایای هر الگوریتم و نحوه پیاده سازیشون با هم متفاوته. در نتیجه تصمیم گیری در این مورد یکمی سخته. اگه از لحاظ سادگی طراحی باشه من پیشنهادم تجزیه کننده پیشگوی بازگشتیه. ولی اگه از لحاظ عملکرد بخوایم بررسی کنیم الگوریتمهای زیادی رو میشه نام برد مثل (LALR(1 و (CLR(0 و .... یکم باید در این مورد با احتیاط تصمیم گرفت. باز هم از دوستان خواهش میکنم که در پروژه بیشتر همکاری کنن.

----------


## amin32

> باز خدا رو شکر شما چهار تا نمره ی دانشگاهی دارید، من که هنوز...!
> 
> ببخشید دوستان،
> اگه به نظرتون کم کاری از من هست، به خاطر این که نمی خوام نظر چرت و پرت بدم،
> اصلا اول اول هدفم این بود که یه برنامه بنویسم که توش به جای چیزایی که می نویسم چند خط کد Assembly بذاره که آدم این قدر از کدهای تکراری عذاب نکشه،
> بعد ... داستان به ساخت کامپایلر رسید،
> خوب گفتم چه بهتره که اصولی باشه و از کسایی که علمشو دارن کمک بگیرم بعد اون قسمت تولید کدهای Assembly رو بنویسم،
> هنوز هم سر حرفم هستم و در قسمت آخر هر کمکی از دستم بر می آد می کنم.
> قبول دارم که این قسمت ها پیچیده تره، طبیعیه که یه کم کند پیش رفته، باز حداقل بحث پیش بره و به نتیجه برسه بهتره.
> ...



الان شما درباره کد میانی ( کد سه آدرسه بهتره) تحقیق کن. چون باید برنامه نوشته شده به زبان ما به این کد میانی تبدیل بشه. بعد از اینکه با این کد آشنا شدی, روی تبدیل اون به کد اسمبلی کار کن. منم فعلا دارم روی طراحی گرامر BNF زبان کار میکنم.
در ضمن بهتره یه اسم برای این زبان انتخاب کنیم که مجبور نشیم هی بگیم زبانمون زبانمون.

----------


## IamOverlord

سلام دوستان، به خاطر وقفه ی طولانی معذرت می خوام.
چرا از کد 3 آدرسه استفاده کنیم؟
اگه می شه یه مثال از اون چیزی که مد نظرتون هست بزنید.
فکر نمی کنم تبدیلش به کد Assembly کار سختی باشه... :متفکر:

----------


## amin32

یک بار کل مراحل کامپایلر رو نام میبرم.

جلوبندی:
 ۱- تحلیلگر لغوی
 ۲-تحلیلگر نحوی
 ۳-تحلیلگر معنایی
 ۴-تولید کننده کد میانی

عقب بندی:
 ۱-بهینه سازی کد میانی
 ۲-تولید کننده کد ( اسمبلی )

البته در آخر کد اسمبلی رو باید به اسمبلر بفرستیم.

خوب. همونطور که میبینید در مرحله چهارم جلوبندی, ما تولید کننده کد میانی رو داریم. این رول اصلی در اکثر زبانهای برنامه نویسی هست که کد زبان مبدا رو به یک کد به زبان میانی تبدیل میکنند و بعد اون به اسمبلی تبدیل میشه.
البته ما میتونیم کد میانی خاص خودمون رو داشته باشیم. ولی کد سه آدرسه هم بد نیست و خیلی سادست. نمونه ای از کدهای سه آدرسه:

(temp:=IntToReal(12
temp2:=id3*temp1
temp3:=id2+temp2
id1:=temp3

البته نیاز به تحقیق بیشتر هست. در ضمن IntToReal برای تبدیل نوع صحیح به اعشاریه.
الان یک مساله ای که فکر منو به خودش مشغول کرده , در مورد اسمبلر هست. آیا میشه از این اسمبلر به این شکل به صورت رایگان استفاده کرد؟ آیا شما مشکلی در مورد ارتباط کامپایلر با اسمبلر ندارید؟
مساله بعد در مورد دستورات هست. الان ما غیر از انتساب , هیچ دستور دیگه ای در زبان نداریم! این هم که بیایم دستورات پایه رو به صورت کتابخانه و با کد اسمبلی بنویسیم, جالبه اما آیا واقعآ استاندارد هست؟

البته اضافه کنم دستورات حلقه و شرطی رو هم داریم .

----------


## IamOverlord

اگه بخوایم از FASM استفاده کنیم Open Source هست. مثل NASM. اما به دلایلی بیش تر FASM رو قبول دارم. ضمنا نیاز به Linker جدا نداریم، خودش Link هم می کنه. برای Linux و Windows و ... هیچ مشکلی نداریم. هم IDE داره و هم برنامه ی Console که با ارسال پارامتر به برنامه ی Console اش می تونیم بگیم، کارامون رو بکنه. از این لحاظ مشکلی نیست.
اگه دیده باشید Pure Basic هم از FASM استفاده می کنه.
اگه بخوایم کد Assembly خالص بدیم به FASM فقط یه FASM.EXE کافیه، اما اگه بخوایم یه سری macro تعریف کنیم (این برامون بهتره تا تعریف زیربرنامه)، باید یه سری (حتی یک) فایل inc. هم داشته باشیم. این کار انعطاف پذیریش بیش تره به نظرم. اگه خواستیم یه تغییری در دستورات پایه ای مون بدیم، فقط کافیه macro ها رو فایل های inc ویرایش کنیم، نه کد Compiler رو!
ضمنا اگه پشیمون شدیم، macro ها رو می تونیم حذف کنیم و خودمون در مرحله ی قبل تر کد macro ها رو تولید کنیم که البته الکی خودمونو اذیت می کنیم.
استاندارد هم هست، چون کد Assembly نهایی در این کار هیچ فرقی با بدون macro اش نداره، چون macro ها برخلاف زیربرنامه ها فقط جایگزین خطوط برنامه می شن.

----------


## IamOverlord

ضمنا یه نظری دارم، اگه کد میانی مون شبیه Instruction های Assembly باشه بهتره (هم راحت تر).
چون نیاز به حداقل پردازش ممکن برای رسوندن کد به Assembler داره؛ یا حتی هیچ پردازشی اگه
کد های سه آدرسیمون رو macro در نظر بگیریم!

----------


## amin32

منظورمو در مورد دستورات پایه نگرفتی! میگم اینکه ما هیچ دستوری مثلا برای ورودی خروجی نداریم و دستورات در کتابخانه ها به شکل اسمبلی هستند یکم با معنای کامپایلر در تناقضه. ببین من فکر میکنم اینکه بعضی از زبانها از دستورات اسمبلی به شکل inline استفاده میکنند یک قابلیت جنبی باشه. نه اینکه کل زبانمون وابسته به این دستورات باشند. من فکر نمیکنم هیچ زبانی وابسته به دستورات inline باشه.

----------


## IamOverlord

همه ی زبان ها به دستورات پایه وابسته هستن اما بعضی ها Assembly رو پایه انتخاب می کنن، بعضی ها یه دستورات سطح بالاتری رو.

----------


## IamOverlord

ببین مثلا شما فرض کن ما برای
Variable1 = Variable2
باید این کد رو تولید کنیم :
MOV AX,variable2
MOV Variable1,AX
خوب می آیم مثلا این رو تعریف می کنیم به عنوان ماکرو:
macro ThreeAddress_MOVE Operand1,CPURegister,Operand2
{
   MOV CPURegister,Operand2
   MOV Operand1,CPURegister
}

بعد مثلا این طوری کد 3 آدرسی تولید می کنیم:

ThreeAddress_MOVE variable1,AX,variable2

منظورم این طوری بود.

----------


## amin32

ببخش ولی تا من مثال دقیق نبینم , قانع نمیشم. تو کتابخانه های gcc هرچی گشتم یک چنین چیزی ندیدم. میتونی مثال واضح از یک زبان و کامپایلر معروف بیاری.

----------


## amin32

> ببین مثلا شما فرض کن ما برای
> Variable1 = Variable2
> باید این کد رو تولید کنیم :
> MOV AX,variable2
> MOV Variable1,AX
> خوب می آیم مثلا این رو تعریف می کنیم به عنوان ماکرو:
> macro ThreeAddress_MOVE Operand1,CPURegister,Operand2
> {
>    MOV CPURegister,Operand2
> ...


این رو بگم که اگه منظورت از کد سه آدرسه همون کد زبان میانی ما هست , اشتباهه و باید از همون فرمهایی که گذاشتم تبعیت کنه. بازم میگم نیاز به تحقیق داره.

----------


## IamOverlord

خوب اگه شما می خواید دستورات پایه مون سطح بالا باشه، قبول، تجربه اش ضرر نداره.
در مورد کد سه آدرسه من هر چه قدر فکر می کنم مزیت روش قبلی رو نسبت به این حالت نمی فهمم:
Instruction FirstOperand , SecondOperand , ThirdOperand
 :متفکر:

----------


## amin32

> خوب اگه شما می خواید دستورات پایه مون سطح بالا باشه، قبول، تجربه اش ضرر نداره.
> در مورد کد سه آدرسه من هر چه قدر فکر می کنم مزیت روش قبلی رو نسبت به این حالت نمی فهمم:
> Instruction FirstOperand , SecondOperand , ThirdOperand


بله این هم میتونه نوعی زبان میانی باشه ولی چون گفتید کد سه آدرسه هست , خواستم تذکر بدم که کد سه آدرسه نیست.
الان به نظرم اگه بخوایم دستورات پایه رو به زبان سطح بالا تعریف کنیم فکر میکنم اولویت با ورودی خروجی باشه.

----------


## amin32

با اینکه خودم مایلم کار اصولی پیش بره ولی احساس میکنم این کد میانی یکم کارو طولانی میکنه. نظرتون چیه؟ کد مبدآ رو مستقیمآ به اسمبلی تبدیل نکنیم؟؟؟!!!! :متفکر:

----------


## IamOverlord

خوب انواع ورودی و خروجی ها چی هستن؟

----------


## IamOverlord

> با اینکه خودم مایلم کار اصولی پیش بره ولی احساس میکنم این کد میانی یکم کارو طولانی میکنه. نظرتون چیه؟ کد مبدآ رو مستقیمآ به اسمبلی تبدیل نکنیم؟؟؟!!!!


نمی گم کد مبدا (اصلاح شد) مستقیما به کد Assembly تبدیل بشه، می گم فقط مشابه باشه با اون کد. این طوری راحت تره، غیر اصولی هم نیست، هر کی هر شکل کد میانی ای که می خواد می تونه داشته باشه.

----------


## amin32

فکر میکنم اول باید به فکر ورودی خروجی ( خواندن و نوشتن ) در کنسول باشیم و بعد هم کار با فایل!

----------


## amin32

> نمی گم کد میانی مستقیما به کد Assembly


این نظر خود من بود. پس شما نظرت اینه که اول به کد میانی تبدیل بشه بعد به اسمبلی دیگه. درسته ؟

----------


## IamOverlord

دقیـقـا...

----------


## amin32

> نمی گم کد میانی مستقیما به کد Assembly تبدیل بشه، می گم فقط مشابه باشه با اون کد. این طوری راحت تره، غیر اصولی هم نیست، هر کی هر شکل کد میانی ای که می خواد می تونه داشته باشه.


فکر میکنم یک اشتباهی شد. من پیشنهاد نکردم *کد میانی* مستقیم به اسمبلی تبدیل بشه چون باید مستقیم باشه. پیشنهاد من این بود که مرحله کد میانی حذف بشه و *کد مبدآ* مستقیمآ به اسمبلی تبدیل بشه. این فقط یه پیشنهاده. نظرت چیه؟

----------


## IamOverlord

> فکر میکنم اول باید به فکر ورودی خروجی ( خواندن و نوشتن ) در کنسول باشیم و بعد هم کار با فایل!


نظرتون چیه در مورد این که دستورات ورودی و خروجی ساختار فراخوانی شون شبیه بقیه ی زیربرنامه ها باشه؟!

----------


## IamOverlord

> فکر میکنم اول باید به فکر ورودی خروجی ( خواندن و نوشتن ) در کنسول باشیم و بعد هم کار با فایل!


نظرتون چیه در مورد این که دستورات ورودی و خروجی ساختار فراخوانی شون شبیه بقیه ی زیربرنامه ها باشه؟!

----------


## IamOverlord

> فکر میکنم یک اشتباهی شد. من پیشنهاد نکردم *کد میانی* مستقیم به اسمبلی تبدیل بشه چون باید مستقیم باشه. پیشنهاد من این بود که مرحله کد میانی حذف بشه و *کد مبدآ* مستقیمآ به اسمبلی تبدیل بشه. این فقط یه پیشنهاده. نظرت چیه؟


آه...! ببخشید.
پست اصلاح شد. منظورم کد *مبدا* بود.
من هم موافقم با این که کد مبدا یا مستقیم به کد Assembly تبدیل بشه یا خیلی مشابه کد های Assembly مون باشه همون طوری که مثال زدم با macro.

----------


## amin32

> نظرتون چیه در مورد این که دستورات ورودی و خروجی ساختار فراخوانی شون شبیه بقیه ی زیربرنامه ها باشه؟!


ببین مثلآ توی زبان c یا basic فکر نمیکنم که شبیه هم باشن. بهتره ما هم به همین رویه عمل کنیم.

----------


## amin32

ولی بهتره خواندن و نوشتن در کنسول با خواندن و نوشتن در فایل به نوعی یک پارچه باشن.

----------


## IamOverlord

برای کار با فایل موافقم،
اما در مورد خوندن و نوشتن به نظرم مثل تابع و زیربرنامه باشن بهتره.

----------


## IamOverlord

اصلا مثل C هر دو روش...! :لبخند گشاده!:

----------


## amin32

OK!
ساختار معرفی کن.

----------


## IamOverlord

Console.WriteLine     ' minevise mire khatte payin
Console.Write         ' faghat minevise
Console.ReadLine      ' mikhoone ta yaroo enter ro bezane
Console.ReadCharacter ' faghat ye character mikhoone
...

این Console قبلشو چی کار کنیم...؟

----------


## amin32

> اصلا مثل C هر دو روش...!


الان که دارم خوب فکر میکنم , اصلآ امکان اینکه خواندن و نوشتن در کنسول رو به شکل تابع در بیاریم نیست چون باز مجبوریم از دستورات اسمبلی در تعریف تابع استفاده کنیم. ولی در مورد فراخوانیش به شکل توابع مشکلی نیست.

----------


## amin32

> Console.WriteLine     ' minevise mire khatte payin
> Console.Write         ' faghat minevise
> Console.ReadLine      ' mikhoone ta yaroo enter ro bezane
> Console.ReadCharacter ' faghat ye character mikhoone
> ...
> 
> این Console قبلشو چی کار کنیم...؟


بهتر نیست از دستورات به تنهایی استفاده بشه؟ (بدون console) . چون این در مفاهیم فعلی زبانمو نیست. به خاطر همین نقطه و console مجبوریم مفاهیم جدیدی رو در زبانمو حمایت کنیم ( شی گرایی!)

----------


## IamOverlord

یا:

use 'iostream'
use 'ScreenClass'

object obj01 : ScreenInterface  ' An object from ScreenClass

obj01.WriteLine ...
obj01.ReadLine ...

' Note : ScreenClass written with iostream routines.

' bara in ke ghablesh console byad:

object Console : ScreenInterface

----------


## IamOverlord

> الان که دارم خوب فکر میکنم , اصلآ امکان اینکه خواندن و نوشتن در کنسول رو به شکل تابع در بیاریم نیست چون باز مجبوریم از دستورات اسمبلی در تعریف تابع استفاده کنیم. ولی در مورد فراخوانیش به شکل توابع مشکلی نیست.


منظورتون رو متوجه نشدم. پیاده سازی توابع زیربرنامه ها در Assembly که مشکلی نداره...

----------


## amin32

> یا:
> 
> use 'iostream'
> use 'ScreenClass'
> 
> object obj01 : ScreenInterface  ' An object from ScreenClass
> 
> obj01.WriteLine ...
> obj01.ReadLine ...
> ...


وای این که دیگه پیچیده تر شد. بازم میگم چهار تا دستور ساده باشه خیلی بهتره.

----------


## IamOverlord

> بهتر نیست از دستورات به تنهایی استفاده بشه؟ (بدون console) . چون این در مفاهیم فعلی زبانمو نیست. به خاطر همین نقطه و console مجبوریم مفاهیم جدیدی رو در زبانمو حمایت کنیم ( شی گرایی!)


!OK
پس اول غیر شئ گراشو می نویسیم مثل C، بعد می شینیم مثل جناب Stroustrup مفاهیم شئ گرایی رو اضافه می کنیم...  :لبخند گشاده!:

----------


## IamOverlord

> وای این که دیگه پیچیده تر شد. بازم میگم چهار تا دستور ساده باشه خیلی بهتره.


اون چهار تا دستور ساده تو iostream قایم شده بودن!
ولی باشه به هر حال فعلا غیر شئ گراشو می نویسیم بعد ... .

----------


## amin32

> منظورتون رو متوجه نشدم. پیاده سازی توابع زیربرنامه ها در Assembly که مشکلی نداره...


چون شما گفتید مثل C از هر دو روش, فکر کردم شاید میخواید برای خواندن و نوشتن باز از توابع کتابخانه ای استفاده کنید. بیخیال....
فعلا تکلیف همین دستورات سطح بالا رو مشخص کنیم.

----------


## IamOverlord

> چون شما گفتید مثل C از هر دو روش, فکر کردم شاید میخواید برای خواندن و نوشتن باز از توابع کتابخانه ای استفاده کنید. بیخیال....
> فعلا تکلیف همین دستورات سطح بالا رو مشخص کنیم.


OK
ولی منظورم scanf من و cin شما بود!
چون scanf خیلی شبیه با زیربرنامه ها و توابعه و cout هم که نه!

اصلا زیاد مهم نیست، چون اگه یه چیزی مثل cout پیاده سازی کنیم که شبیه زیربرنامه ها نباشه، خیلی راحت می شه زیربرنامش هم نوشت دیگه...!

خوب حالا نظر شما برای ورودی و خروجی چیه؟
این که ورودی و خروجی Console و File ها شبیه هم باشن جالب بود اما چه طوری؟

----------


## amin32

> OK
> خوب حالا نظر شما برای ورودی و خروجی چیه؟
> این که ورودی و خروجی Console و File ها شبیه هم باشن جالب بود اما چه طوری؟


مثلآ در vb دستور print هم میتونه در نوشتن روی فرم به کار بره هم در نوشتن در فایل.

----------


## IamOverlord

مثل QBASIC باشه [تقریبا]؟!

----------


## amin32

نباید شبیه زبانی دیگه باشه؟
در ضمن همونطور که گفتم من فقط تا اواسط اسفند, وقت آزاد دارم. بعدش به خاطر درسهام نمیتونم فعلآ وقتم رو برای این کار بگذارم. :افسرده:

----------


## IamOverlord

کی فکر می کنی وقتت آزاد می شه؟!

----------


## amin32

تا آخر ترم !

ولی متآسفانه تا همینجاش خیلی وقت و از دست دادیم.
*شاید* بتونم تا اون موقع تحلیلگر نحوی رو تکمیل کنم و باقی رو بذاریم برای بعد.

----------


## Slytherin

اعتماد به نفستون توی حلقم :لبخند گشاده!: 
صفحه 1 تایپیک بودم، اونجا بحث بود که ساختار لغات مشخص بشه! الان اومدم صفحه 29 می بینم که هنوز داره در مورد ساختار کلمات کلیدی و نحو برنامه بحث میشه! :لبخند گشاده!: 
کارتون قابل تحسین هست ولی فکر کنم حتی اگر بخواهید به یک نتیجه ساده برسید سال ها طول بکشه...
یک پیشنهاد:
چون پروژه تجاری نیست صرفا جنبه آموزشی داره به نظرم اول یک زبان ناقص طراحی کنید و اگر جواب داد بعد روی کامل کردنش تحت یک پروژه کاملا جدید و مستقل کار کنید...

----------


## IamOverlord

مشکل وقته! وگرنه کار ادامه پیدا می کنه. کس دیگه هم غیر از جناب *amin32* نیست که کارو سریع تر ادامه بدیم...

----------


## manocher.a

سلام بر دوستان عزیز 
ضمن عرض تبریک سال نو میخواستم عرض کنم من هم تاپیک دارم دنبال میکنم ولی خبری نشد حالا که من میخوام یک پروژه تجاری اینجا ارائه بدم بلکه شما دوستان بتونید روی این موضوع کمکی به من بکنید شاید روش اجرا جنبه ایی آموزشی هم شد
من در حال نوشتن یک پلتفورم برای بازار فارکس هستم و میخوام با ساخت کامپلیر ساده بتونم اندیکاتورهای نوشته شده در این مورد به این پلتفرم اضافه کنم در زیز هم نمونه یکی از اندیکاتورها اضافه کردم حالا ضمن نوشته های قبلی دوستان هر کدوم از دوستان که توانایی دارن راهنمایی کنند(از همه دوستان تشکر میکنم)
//+------------------------------------------------------------------+
//|                                                  Heiken Ashi.mq4 |
//|                      Copyright c 2004, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
//| For Heiken Ashi we recommend next chart settings ( press F8 or   |
//| select on menu 'Charts'->'Properties...'):                       |
//|  - On 'Color' Tab select 'Black' for 'Line Graph'                |
//|  - On 'Common' Tab disable 'Chart on Foreground' checkbox and    |
//|    select 'Line Chart' radiobutton                               |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2004, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net"

#property indicator_chart_window
#property indicator_buffers 4
#property indicator_color1 Red
#property indicator_color2 White
#property indicator_color3 Red
#property indicator_color4 White
#property indicator_width1 1
#property indicator_width2 1
#property indicator_width3 3
#property indicator_width4 3

//----
extern color color1 = Red;
extern color color2 = White;
extern color color3 = Red;
extern color color4 = White;
//---- buffers
double ExtMapBuffer1[];
double ExtMapBuffer2[];
double ExtMapBuffer3[];
double ExtMapBuffer4[];
//----
int ExtCountedBars=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//|------------------------------------------------------------------|
int init()
  {
//---- indicators
   SetIndexStyle(0,DRAW_HISTOGRAM, 0, 1, color1);
   SetIndexBuffer(0, ExtMapBuffer1);
   SetIndexStyle(1,DRAW_HISTOGRAM, 0, 1, color2);
   SetIndexBuffer(1, ExtMapBuffer2);
   SetIndexStyle(2,DRAW_HISTOGRAM, 0, 3, color3);
   SetIndexBuffer(2, ExtMapBuffer3);
   SetIndexStyle(3,DRAW_HISTOGRAM, 0, 3, color4);
   SetIndexBuffer(3, ExtMapBuffer4);
//----
   SetIndexDrawBegin(0,10);
   SetIndexDrawBegin(1,10);
   SetIndexDrawBegin(2,10);
   SetIndexDrawBegin(3,10);
//---- indicator buffers mapping
   SetIndexBuffer(0,ExtMapBuffer1);
   SetIndexBuffer(1,ExtMapBuffer2);
   SetIndexBuffer(2,ExtMapBuffer3);
   SetIndexBuffer(3,ExtMapBuffer4);
//---- initialization done
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//---- TODO: add your code here
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   double haOpen, haHigh, haLow, haClose;
   if(Bars<=10) return(0);
   ExtCountedBars=IndicatorCounted();
//---- check for possible errors
   if (ExtCountedBars<0) return(-1);
//---- last counted bar will be recounted
   if (ExtCountedBars>0) ExtCountedBars--;
   int pos=Bars-ExtCountedBars-1;
   while(pos>=0)
     {
      haOpen=(ExtMapBuffer3[pos+1]+ExtMapBuffer4[pos+1])/2;
      haClose=(Open[pos]+High[pos]+Low[pos]+Close[pos])/4;
      haHigh=MathMax(High[pos], MathMax(haOpen, haClose));
      haLow=MathMin(Low[pos], MathMin(haOpen, haClose));
      if (haOpen<haClose) 
        {
         ExtMapBuffer1[pos]=haLow;
         ExtMapBuffer2[pos]=haHigh;
        } 
      else
        {
         ExtMapBuffer1[pos]=haHigh;
         ExtMapBuffer2[pos]=haLow;
        } 
      ExtMapBuffer3[pos]=haOpen;
      ExtMapBuffer4[pos]=haClose;
 	   pos--;
     }
//----
   return(0);
  }
//+------------------------------------------------------------------+

----------


## amin32

سلام من برگشتم.
خب بعد از این وقفه طولانی تصمیم گرفتم دوباره تا جایی که میتونم روی پروژه کار کنم. البته این رو بگم که باز هم بودنم در پروژه قطعی نیست و ممکنه به خاطر مشکلات شخصی زیادی که دارم  پروژه رو رها کنم.همینجا از دوستان و اساتید دیگه هم دعوت میکنم که اگه در پروژه مشارکت کنند.بگذریم...
یک تغییر کوچیک مد نظرم هست و اون اینه که به خاطر جلوگیری از بعضی سوء استفاده های احتمالی تا زمان تکمیل شدن کامل پروژه *کدهای اصلی فازها*  فقط در اختیار اعضای گروه قرار میگیره. البته بحث و تحلیل کدها و الگوریتم ها و مسائل دیگه به صورت عمومی انجام میشه.
یک سوالی هم برام پیش اومده .در مورد استفاده از اسمبلر FASM که ما اینقدر برای تکمیل پروژه روش حساب کردیم آیا مشکلی از لحاظ قانونی و کپی رایت نداره.

----------


## IamOverlord

...سلام!
فکر می کنم مشکلی نباشه، این جا رو ببینید: www.bttr-software.de/forum/forum_entry.php?id=8727

----------


## amin32

خب پس مثل اینکه مشکلی از این بابت نیست.
میرسیم به ساخت EBNF زبان برای پیاده سازی تحلیلگر نحوی.

----------


## IamOverlord

فکر می کنم قبلا یه کدی برای تحلیلگر لغوی نوشته بودین...
خوب برای ساختار EBNF یه ساحتار کلی پیشنهاد بدید، روش کار کنیم، یه سری چیزهای اصولی هم که در اکثر ساختار ها مشترکه،...

----------


## amin32

> فکر می کنم قبلا یه کدی برای تحلیلگر لغوی نوشته بودین...
> خوب برای ساختار EBNF یه ساحتار کلی پیشنهاد بدید، روش کار کنیم، یه سری چیزهای اصولی هم که در اکثر ساختار ها مشترکه،...


بله تحلیلگر لغوی تقریبآ کامله. در مورد ساختار نحوی هم که قبلآ در موردش بحث کردیم:

https://barnamenevis.org/showthread.p...=1#post1428198

و برای ساختار حلقه:
https://barnamenevis.org/showthread.p...=1#post1428655

فقط الان که دارم دقت میکنم با توجه به ساختار حلقه باید کلمه Check رو هم به کلمات کلیدی در تحلیلگر لغوی اضافه بشه که چیز مهمی نیست. الان باید با توجه به ساختاری که با مثال ایجاد کردیم EBNF رو بسازیم ولی باید دقت کنیم که گرامرها نباید ابهام یا بازگشتی چپ داشته باشند.

----------


## IamOverlord

چون تا حالا یه گرامر درست و حسابی ننوشتم، اول یه نگاهی بندازیم به بقیه ی گرامر ها و روی اون ها کار کنیم و بعد گرامر خودمون رو بنویسیم...
این هم یه نمونه ی خوب: rosettacode.org/wiki/BNF_Grammar

----------


## emadfa

سلام بر دوستان.
من همه پست های این تاپیک رو بررسی نکردم ولی تعداد زیادی از اون ها رو خوندم...

به دلیل علاقه ای که به طراحی کامپایلر ( و به شکل خاص تر parse کردن یک متن در نرم افزار خودم ) داشتم با کامپایلر و الگوریتم های طراحی اون آشنایی زیادی دارم...

دوستان... فراموش نکنید که تقریبا در اکثر کامپایلرهای دنیا (یا به عبارتی همه کامپایلرها) دو بخش اول یعنی تحلیلگر لغوی و تحلیلگر نحوی به هیچ عنوان دستی انجام نمی شه... یعنی برای نوشتن تحلیل گر لغوی  و نحوی طراحان کامپایلر حتی شاید یک خط کد هم ننویسند... بلکه از ابزارهای آماده استفاده می کنند...
ابزارهای زیادی وجود داره...

به عنوان مثال برای طراحی تحلیلگر لغوی... وقتی زبان و واژگان زبان (توکن ها) رو طراحی کردیم... باید تحت یک فرمت مشخص این توکن ها رو به عنوان ورودی به ابزاری مثل LEX یا FLEX بدیم... خود این ابزار برای ما Scanner رو تولید می کنه و به ما یک کد و برنامه میده...

شما تصور کنید برای طراحی یک کامپایلر برای زبانی مثل C اگر بخوایم Scanner رو دستی طراحی کنیم چقدر کد وحشتناک می شه... DFD ما برای اسکنر مثلا شامل حدود 3000 state می شه... برای طراحی این states با جدول انتقال (Transition-Diagram) یا روش switch-case (دو روش طراحی scanner بدون ابزار) شاید نیاز بشه ماه ها وقت بزاریم... در نهایت هم احتمالا خطا و اشتباه به دلیل پیچیدگی وجود خواهد داشت و البته دو فاکتور مهم در مهندسی نرم افزار یعنی "وقت" و "هزینه" رو از دست میدیم... این رو میشه با ابزار در مدت زمان کوتاهی با دقت بسیار بالا انجام داد (اگر زبان و توکن ها طراحی شده باشه شاید کمتر از چند ساعت برای نوشتن و تولید scanner زمان نیاز باشه) و در عوض تمرکزمون رو روی بهینه سازی ها و تحلیل گر معنایی و سایر قسمت های مهم کامپایلر بزاریم...


برای طراحی parser یا تحلیل گر معنایی هم دقیقا همین طوره... دونستن مفاهیم پارسر مثل (SLR(1 یا گرامرهای (LL(1 یا (CLR(1 یا ... ضروری هست و باید بلد باشیم (چون به ما دید میده و گاهی اوقات حتی کمک هم میکنه) اما در عمل از هیچ کدوم از این ها استفاده نمی کنیم بلکه به عنوان مثال از ابزاری به نام  YACC (مخفف Yet Another Compiler Compiler) استفاده می کنیم... ما به ابزار همه گرامر های زبان رو میدیم و ابزار به شکل اتوماتیک الگوریتم تحلیل پایین به بالا (LALR1)  رو پیاده سازی می کنه و به ما مثلا کد C می ده.... در واقع تنها کاری که باید انجام بدیم طراحی همه گرامرهای زبان هست نه پیاده سازی parser مربوط به این گرامرها
فراموش نکنید طراحی تحلیل گر نحوی به شکل دستی کار بسیار دقیق و زمانبری هست و البته با وجود این ابزارهای خودکار و قدرتمند بیهوده... چون اگر صدها یا هزاران گرامر داشته باشیم باید برای تک تک گرامرها الگوریتمهای تحلیل نحوی (پایین به بالا یا بالا به پایین) مثلا (LALR(1 (یکی از قویترین الگوریتم های parser پایین به بالا) رو اعمال و پیاده سازی کنیم و چنین کاری با داشتن ابزار بیهوده است...

از این ابزارها و ابزارهای مشابه تقریبا همه شرکت های مشهور حتی طراحان جاوا یا مایکروسافت (برای طراحی کامپایلر) استفاده می کنند. بنابراین پیشنهاد می کنم از نرم افزارهای قدرتمند برای تولید حداقل این دو بخش از کامپایلر استفاده کنید...

موفق باشید...

----------


## IamOverlord

سلام دوست عزیز،
البته توجه داشته باشیم فعلا این پروژه جنبه ی یادگیری و سرگرمی داره، نه جنبه ی تجاری...
اما پیشنهاد خوبیه...  :متفکر:

----------


## amin32

> سلام بر دوستان.
> من همه پست های این تاپیک رو بررسی نکردم ولی تعداد زیادی از اون ها رو خوندم...
> 
> به دلیل علاقه ای که به طراحی کامپایلر ( و به شکل خاص تر parse کردن یک متن در نرم افزار خودم ) داشتم با کامپایلر و الگوریتم های طراحی اون آشنایی زیادی دارم...
> 
> دوستان... فراموش نکنید که تقریبا در اکثر کامپایلرهای دنیا (یا به عبارتی همه کامپایلرها) دو بخش اول یعنی تحلیلگر لغوی و تحلیلگر نحوی به هیچ عنوان دستی انجام نمی شه... یعنی برای نوشتن تحلیل گر لغوی و نحوی طراحان کامپایلر حتی شاید یک خط کد هم ننویسند... بلکه از ابزارهای آماده استفاده می کنند...
> ابزارهای زیادی وجود داره...
> 
> به عنوان مثال برای طراحی تحلیلگر لغوی... وقتی زبان و واژگان زبان (توکن ها) رو طراحی کردیم... باید تحت یک فرمت مشخص این توکن ها رو به عنوان ورودی به ابزاری مثل LEX یا FLEX بدیم... خود این ابزار برای ما Scanner رو تولید می کنه و به ما یک کد و برنامه میده...
> ...


سلام دوست عزیز.
من تا حدودی با حرفتون موافقم یعنی اینکه استفاده از Yacc و bison میتونه به تولید تحلیلگر نحوی سرعت ببخشه. البته فکر میکنم در مورد تحلیلگر لغوی فرق چندانی نداره و ما توستیم اون رو به راحتی به صورت دستی بسازیم. با توجه به تعداد حالتهای لغات:
https://barnamenevis.org/showthread.p...=1#post1433481

همونطور که دوستمون گفتن چون ما هدفمون بیشتر جنبه یادگیری داره فکر میکنم بهتر باشه به شکل دستی ساخته بشه.بازم ممنون از نظرتون. ازتون دعوت میکنم اگر مایل بودید در پروژه با ما همکاری کنید.

----------


## amin32

دو تا لینک خوب برای آشنایی بهتر با EBNF و گرامرها:

http://c.comsci.us/syntax/expression/ebnf.html

http://cs.lmu.edu/~ray/notes/syntax/

----------


## amin32

یه مشکلی در طراحی EBNF وجود داره.این گرامر رو نگاه کنید:


<program>::=<uses><imports><define><main><function  s>
<Uses>::={<Use>{NEWLINE}+}*
<Use>::= <USE_KEY><STRING>


اینجا ما تو خط اول نحو کلی یک برنامه به زبانمون رو بیان کردیم. همونطور که میبینید برناممون با تعریف Use ها شروع میشه ( کتابخانه ها) . بعدش import ها رو داریم و همینطور تا آخر. ولی مشکل از خط دوم شروع میشه. ببینید ما متآسفانه از کاراکتر خط جدید به عنوان کاراکتر هماهنگ کننده ( جدا کننده دستورات ) استفاده کردیم. یعنی بین هر دستور مستقل باید یک یا چند کاراکتر خط جدید وجود داشته باشه (علامت "+" بعد از Newline به همین معنی هست ) . مشکل اینجاست که ممکنه مثلآ برنامه نویس بخواد یه برنامه که فقط از یک دستور فراخوانی کتابخانه (USE) تشکیل شده رو بنویسه و بعد از این دستور هم قاعدتآ نیازی به درج خط جدید نیست. این درحالیه که با توجه به این گرامر , تحلیلگر نحویمون از این برنامه ایراد میگیره. :متفکر:

----------


## IamOverlord

خوب ببینید می شه از | استفاده کنیم، یعنی اون حالت رو هم داخل خط اول گرامر در نظر بگیریم.
use فقط include می کنه؟ اگه آره، پس بهتره کاری کنیم که use رو بشه در هر قسمتی از کد استفاده کنیم.
ضمنا در این صورت قبل این که این مراحل تحلیل شروع بشه، بهتر نیست که دنبال عبارت های use بگردیم و محتوای فایل مورد نظر رو جایگزین use کنیم؟ یه replace ساده...  :متفکر:

----------


## amin32

> خوب ببینید می شه از | استفاده کنیم، یعنی اون حالت رو هم داخل خط اول گرامر در نظر بگیریم.


لطفآ اگه امکانش هست گرامرش رو بنویس. اینطوری نمیشه متوجه شد.




> use فقط include می کنه؟ اگه آره، پس بهتره کاری کنیم که use رو بشه در هر قسمتی از کد استفاده کنیم.


به نظرت منطقی تر نیست که کتابخانه ها در ابتدای برنامه معرفی بشن؟




> ضمنا در این صورت قبل این که این مراحل تحلیل شروع بشه، بهتر نیست که دنبال عبارت های use بگردیم و محتوای فایل مورد نظر رو جایگزین use کنیم؟ یه replace ساده...


در این مورد باید بعدآ بیشتر تحقیق کنیم. چون این رفتار در مورد ماکروها اتفاق می افته. ولی از این مطمئنم که تا قبل از تحلیل برنامه اصلی نباید در کدهای نوشته شده توسط برنامه نویس دست برد چون ممکنه مثلآ دستور use نوشته شده از نظر نحوی اشباه باشه. از من میپرسی میگم که این کارها باید در مرحله تولید کد میانی انجام بشه.

----------


## IamOverlord

تا جایی که فهمیدم این دستور use اگه فقط به معنای جایگزینی محتوای فایل باشه، کار قسمت preprocessor هست اصولا... از اون جایی که دستوری مثل if هم در قسمت preprocessor داریم فکر می کنم جرف شما درست باشه، چون این ها هم مثل بقیه ی قسمت های کد نیاز به تحلیل دارند...
اما اگه مثل زبان c مکان زیربرنامه ها نسبت به هم مهمه، فکر می کنم بهتره قابلیت نوشتن use در جاهای مختلف رو بذاریم، چون مثلا ممکنه شما در فایل کتابخانه تون یه زیربرنامه ی B داشته باشید که از زیربرنامه ی A استفاده می کنه و می خواید زیربرنامه ی A رو بعدا در  بیرون از فایل کتابخانه تون قبل از دستور use تعریف کنید، یه کارهای دیگه ای مثل استفاده از use لا به لای import ها که در این حالت در فایل کتابخانه مثلا تعدای import پرکاربرد نوشته شده یا ...
به نظرم یه مقدار باید آزادی عمل بدیم.

----------


## amir22448

من هستم. ولی من نمی دونم چجوری می خوای این کار رو بکنی.به نظر من با زبان C#‎ این کار رو بکنیم بهتره. من که نمی دونم چجوری بسازیم.خیلی سخته. باید اول برای هر کدی که می خوای یه متغیر تعریف کنی و کد خودتو در اون متغیر قرار بدید. ولی همین که به برنامه بفهمونی که این کد چکار می کنه خودش خیلی سخته. :متفکر: .ولی من هستم.با هم درستش می کنیم.

----------


## amin32

> تا جایی که فهمیدم این دستور use اگه فقط به معنای جایگزینی محتوای فایل باشه، کار قسمت preprocessor هست اصولا... از اون جایی که دستوری مثل if هم در قسمت preprocessor داریم فکر می کنم جرف شما درست باشه، چون این ها هم مثل بقیه ی قسمت های کد نیاز به تحلیل دارند...
> اما اگه مثل زبان c مکان زیربرنامه ها نسبت به هم مهمه، فکر می کنم بهتره قابلیت نوشتن use در جاهای مختلف رو بذاریم، چون مثلا ممکنه شما در فایل کتابخانه تون یه زیربرنامه ی B داشته باشید که از زیربرنامه ی A استفاده می کنه و می خواید زیربرنامه ی A رو بعدا در بیرون از فایل کتابخانه تون قبل از دستور use تعریف کنید، یه کارهای دیگه ای مثل استفاده از use لا به لای import ها که در این حالت در فایل کتابخانه مثلا تعدای import پرکاربرد نوشته شده یا ...
> به نظرم یه مقدار باید آزادی عمل بدیم.


قبل از هر چیز یه توضیح در مورد مسآله اول که عنوان کردی بدم. یک فایل کتابخانه میتونه شامل هزاران خط کد باشه ( و شاید هزاران تابع ) که برنامه نویس نیازی به همه اونها نداره. پس این که بخوایم به ازای هر معرفی کتابخانه , کل کتابخانه رو در کدها جایگزین کنیم یک کار بیهوده هست و باعث پایین آمدن شدید سرعت کامپایل میشه. کاری که باید انجام بشه اینه که برای هر فراخوانی تابع اول باید در توابع تعریف شده در خود برنامه به دنبال اون تابع بگردیم.اگر پیدا نشد در کتابخوانه های معرفی شده به دنبال آن تابع میگردیم. واگر باز هم پیدا نشد باید خطای تابع تعریف نشده رو صادر کنیم.که این اینکارها همگی مربوط به فازهای تحلیلگر معنایی و تولید کد میانی هست. پس بهتره فعلآ بهش فکر نکنیم.
اما اینکه use ها فقط در ابتدای برنامه به کار برده شوند یا در هر جای برنامه ,مربوط میشه به تحلیلگر نحوی و باید همین جا مشخص بشه. راستش با مثالی که زدی من هنوز نتونستم لزوم این که کتابخانه ها در هر جا تعریف بشند رو درک کنم. ببین کتابخونه ها یک فایل مستقل هستند. یعنی هیچ وابستگی به برنامه ای که قراره نوشته بشه ندارند. اگر هم قراره از یک تابع خارجی استفاده کنند , اون تابع در یک کتابخونه دیگه قرار میگیره و در کتابخونه مورد نظر معرفی میشه. دقیقآ مثل کاری که در مورد Include ها انجام میشه. اگر باز هم دلیل قانع کننده ای برای نظرت داشتی در میان بزار.تا در این مورد تصمیم گیری کنیم.
ضمنآ یک نکته هم خدمت دوستانی که فکر میکنند کار ایجاد ساختار لغوی و نحوی یک زبان جدید آسان هست و نیاز به صرف زمان چندانی نداره عرض میکنم. ببینید شما یک کتاب آموزش زبان برنامه نویسی رو در نظر بگیرید. چنین کتابی میتونه حجمی برابر 100 تا 1000 صفحه داشته که قطعآ حداقل 50 درصد اون صرف توضیح ساختار لغوی و نحوی زبان میشه . این در حالیه که تولید ساختار لغوی و نحوی یک زبان جدید به عوامل دیگه ای مثل خلاقیت و در نظر گرفتن موانع پیاده سازی نیازمند هست. شاید جالب باشه بدونید که فقط ابداع ساختار یک زبان جدید که جالب و قابل پیاده سازی باشه هم در علوم کامپیوتر میتونه ارزشمند باشه. و طراحی کامپایلر میتونه ارزش زبان رو به شکل ملموس تری نشون بده.

----------


## amin32

به نظرم فعلآ بهتره به قدرت و انعطاف زبان فکر نکنیم. هر تغییری رو میشه بعدن بهش اضافه کرد. الان باید روی پیاده سازی و مشکلاتی که ممکنه پیش بیاد فکر کنیم. وگرنه اگه بخوایم فقط همینطور روی گسترش زبان فرضیمون کار کنیم به جایی نخواهیم رسید. به نظرم حتی اگه ساده کردن و حذف بعضی قابلیتها میتونه به پیاده سازی کمک کنه, باید اینکار رو انجام بدیم.

----------


## amin32

با توجه به مشغله زیاد خودم باز هم از دوستان دیگه که در زمینه کامپایلر , پارسرها و مباحث مرتبط ( به هر زبانی ) کار کردن دعوت میکنم در پروژه مشارکت کنند.

----------


## IamOverlord

سلام...
یه مدتیه سرم شلوغه، ولی همچنان سعیم رو می کنم...

خوب، اون گرامری رو که نوشتین این طوری تغییر دادم:
<program>::=<sec_uses_imports><sec_defines>
<sec_defines>::={<define>}
<define>::=<def_global_variables>|<def_procedure_m  ain>|<def_procedure>|<def_function>|<def_structure  >|<def_class>
<sec_uses_imports>::={<use_import>}
<use_import>::=<use>|<import>
<use>::=<use_key><file_address>|<use_key><quoted_f  ile_address>
<use_key>::=
<import>::=

البته چون من زیاد وارد نیستم تو زمینه ی نوشتن گرامر، لطفا دوستان همکاری کنند، درستش کنیم.  :چشمک:

----------


## amin32

> سلام...
> یه مدتیه سرم شلوغه، ولی همچنان سعیم رو می کنم...
> 
> خوب، اون گرامری رو که نوشتین این طوری تغییر دادم:
> <program>::=<sec_uses_imports><sec_defines>
> <sec_defines>::={<define>}
> <define>::=<def_global_variables>|<def_procedure_m  ain>|<def_procedure>|<def_function>|<def_structure  >|<def_class>
> <sec_uses_imports>::={<use_import>}
> <use_import>::=<use>|<import>
> ...



ببین با توجه به این صفحه: 

قسمت define فقط متغیرهای عمومی رو در بر میگیره و توابع و روالها رو شامل نمیشه ! 
این گرامر داره یک زبان کاملآ  متفاوت رو تعریف میکنه!
یک پیشنهادی که بهت میکنم اینه که فعلآ به هیچ وجه قابلیت جدیدی رو به زبان اضافه نکنی.( مثل def_class) .  به نظر من پیاده سازی یک زبان خیلی خیلی ساده هم میتونه مشکلات خودش رو داشته باشه.  بیخود نیست که تعداد کامپایلرها تقریبآ کم هست و هنوز در بعضی از موارد کمبودهایی وجود داره. پس بهتره فعلآ  روی همین قابلیتها کار کنیم.

----------


## amin32

لازم دیدم کمی در مورد تحلیلگر نحوی و عمکردش توضیح بدم. ببینید ما تا اینجای کار تحلیلگر لغوی رو نوشتیم. کار تحلیلگر لغوی این بود که نوع هر کلمه به کار رفته در کد برنامه رو تشخیص بده  و به ازای هر لغت, نوعش رو که به اون توکن  گفته میشه رو برای فاز بعدی بفرسته. در پایان این فاز ما علاوه بر کد اصلی برنامه , یک سری توکن رو داریم که نشون میده برنامه نویس انواع مختلف لغات ( عدد صحیح , رشته , کلمه کلیدی , عملگرها و.... ) رو با چه ترتیبی در کنار هم قرار داده که بهش ساختار نحوی برنامه گفته میشه . از طرفی ما به عنوان طراح کامپایلر باید بررسی کنم که این ساختار نحوی از ساختار نحوی زبان ما تبعیت میکنه یا خیر. اینجاست که بحث گرامرها( در اینجا EBNF) مطرح میشه. ما با استفاده از گرامرها و قابلیتهای اون در واقع ساختار نحوی زبان رو توصیف میکنیم. تا با پیاده سازی اون بتونیم این ساختار رو با ساختار کد نوشته شده برنامه نویس مقایسه کنیم و در صورت عدم تطبیق به کاربر هشدار لازم رو بدیم.

----------


## amin32

همونطور که در اینجا توضیح دادم :
https://barnamenevis.org/showthread.p...=1#post1545873

مشکل ما این هست که از کاراکتر خط جدید به عنوان هماهنگ کننده استفاده کردیم. و این یکم پیاده سازی گرامر رو مشکل کرده. فکر میکنم اگه مثل زبان  C ( که از ';' استفاده کرد) و خیلی  زبانهای دیگه , ما هم از یک کاراکتر خاص استفاده کنیم , احتمالآ باید این مشکل رفع بشه. البته با همین کاراکتر خط جدید هم غیر ممکن نیست ولی یکمی پیچیده میشه. :متفکر:

----------


## IamOverlord

> ولی مشکل از خط دوم شروع میشه. ببینید ما متآسفانه از کاراکتر خط جدید به عنوان کاراکتر هماهنگ کننده ( جدا کننده دستورات ) استفاده کردیم. یعنی بین هر دستور مستقل باید یک یا چند کاراکتر خط جدید وجود داشته باشه (علامت "+" بعد از Newline به همین معنی هست ) . مشکل اینجاست که ممکنه مثلآ برنامه نویس بخواد یه برنامه که فقط از یک دستور فراخوانی کتابخانه (USE) تشکیل شده رو بنویسه و بعد از این دستور هم قاعدتآ نیازی به درج خط جدید نیست. این درحالیه که با توجه به این گرامر , تحلیلگر نحویمون از این برنامه ایراد میگیره.


یعنی حداقل 1 کاراکتر خط جدید باید در هر کدی وجود داشته باشه؟ در این صورت به نظر من باید قبل از این که کد رو تحویل بدیم، خودمون یه سری ویرایش های جزئی روش بکنیم؛ مثلا به آخر هر کدی یه کاراکتر خط جدید اضافه کنیم...

----------


## IamOverlord

گرامر BASIC رو تو همون لینکی که گذاشتم نگاه کردم:
<Lines>       ::= Integer <Statements> NewLine <Lines> 
                | Integer <Statements> NewLine
Integer رو که بی خیال، اما بقیش همون مشکلی که ما داریم رو داره، احتمالا اون ها هم یه ویرایش هایی قبل از تحلیل ها انجام می دن... البته برای حل مشکل ببینید این جواب می ده؟:
<Lines>		::= <Statements> NewLine <Lines> 
		  | <LastLineOfCode>
<LastLineOfCode>::= <Statements> NewLine
		  | <Statements>

----------


## amin32

> یعنی حداقل 1 کاراکتر خط جدید باید در هر کدی وجود داشته باشه؟ در این صورت به نظر من باید قبل از این که کد رو تحویل بدیم، خودمون یه سری ویرایش های جزئی روش بکنیم؛ مثلا به آخر هر کدی یه کاراکتر خط جدید اضافه کنیم...


نه منظورم این نبود که فقط یک کاراکتر خط جدید داشته باشیم. منظورم اینه که کلآ کاراکتر هماهنگ کننده رو تغییر بدیم و یک کاراکتر خاص انتخاب کنیم. در ضمن اینو هم در نظر بگیر که اگه قرار باشه ما به جای برنامه نویس برای هر کد یک کاراکتر خط جدید اضافه کنیم ,  ممکنه کاربر به اشتباه دو تا دستور رو بدون خط جدید وارد کنه که در اون صورت تشخیصش برای ما خیلی مشکل میشه و پیاده سازی چنین چیزی میتونه خیلی کار رو پیچیده تر کنه.

----------


## IamOverlord

اون گرامر بالا در مورد چند تا New Line بین 2 خط کد مشکل داره... فکر می کنم این بهتر باشه:
<NL>			::= NewLine <NL>
                          | NewLine
<Lines>			::= <Statements> <NL> <Lines> 
		  	  | <LastLineOfCode>
<LastLineOfCode>	::= <Statements> <NL>
		  	  | <Statements>

----------


## amin32

من باز هم پیشنهاد میکنم از یک کاراکتر هماهنگ کننده دیگه استفاده کنیم . یا اصلآ مثل HTML دستورات رو داخل تگها قرار بدیم. در هر دو صورت به راحتی میتونیم مشکل خط جدید رو حل کنیم و فقط کافیه در گرامر بعد از هر دستور به تعداد صفر تا بینهایت خط جدید رو در نظر بگیریم.

----------


## IamOverlord

ببینید با اون تعریف NL که در آخرین کد گذاشتم اون مشکل تعداد کاراکتر های خط جدید بین دو خط حله... من زیاد با ;... راحت نیستم! پیشنهاد می کنم همین مشکل رو با توجه به گرامر هایی که بقیه نوشتن حل کنیم...

----------


## amin32

> ببینید با اون تعریف NL که در آخرین کد گذاشتم اون مشکل تعداد کاراکتر های خط جدید بین دو خط حله... من زیاد با ;... راحت نیستم! پیشنهاد می کنم همین مشکل رو با توجه به گرامر هایی که بقیه نوشتن حل کنیم...


OK !
با اینکه فکر میکنم استفاده از کاراکتر هماهنگ کننده , ساخت گرامر و پیاده سازی تحلیلگر رو به شدت سادهتر میکنه ولی با راهکارت موافقم.

----------


## amin32

یک فکر خوب به ذهنم زد:


<program>::=<uses><imports><define><main><function  s>
<Uses>::={<Use>}*
<Use>::= <USE_KEY><STRING><Coordinator>
<Coordinator>::={NEWLINE}+|{NEWLINE}* <EOF_key>


مشکل رو با لغت پایان فایل (EOF) حل کردم. Coordinator به عنوان هماهنگ کننده تعریف شده که میتونه " یک یا بیشتر خط جدید باشه" یا میتونه "صفر یا چند خط جدید و یک کاراکتر پایان فایل" باشه. مورد اول برای دستورات میانی هست و مورد دوم برای دستور پایانی که میتونه خط جدید داشته باشه یا نداشته باشه. با این حساب فکر میکنم این مشکل حل شده باشه. فقط باید در تحلیلگر لغوی لغت EOF رو هم به کلمات کلیدی اضافه کنیم.

----------


## IamOverlord

!===================
! CHARACTER SETS
!===================

{String Char} = {All Valid} - ["]
{ID Tail} = {Alphanumeric} + [_]

!=============
! LITERALS
!=============

StringLiteral = '"' ( {String Char} | '""' )* '"'
ID = {Letter} {ID Tail}*

!==========
! RULES
!==========

<program> ::= <NLOpt> <GlobalStmtList>

<GlobalStmtList> ::= <GlobalStmt> <GlobalStmtList>
                   | 

<GlobalStmt> ::= <UseStmt>
               | <ImportStmt>
               | <DefineBlock>
               | <ProcdureDecl>
               | <FunctionDecl>

<UseStmt> ::= 'Use' StringLiteral <NL>

<NL> ::= {NewLine}+|{NewLine}* <EOF_key>

<NLOpt> ::= <NL>
          |

<ProcedureDecl> ::= 'Procedure' ID <MethodArgList> <NL> <MethodStmtList> 'End' 'Procedure' <NL>

<FunctionDecl> ::= 'Function' ID <MethodArgList> <Type> <NL> <MethodStmtList> 'End' 'Function' <NL>

----------


## amin32

دوستان با توجه به مشغله خیلی خیلی  زیادی که دارم فکر میکنم دیگه نتونم برای این پروژه وقت بزارم. دوستانی که مایل هستند میتونند پروژه رو ادامه بدند.

----------


## کاظم فلاحی خواه

راستش منم می خوام ide (ساخت بازی و برنامه برای موبایل)درست کنم که با زبان بیسیک فارسی باشه و کدها رو تبدیل به جاوا کنه بعد با ماشین جاوا برنامه ساخته شده رو اجرا کنه .
دوستان کمکم کنید .

----------


## IamOverlord

سلام دوست عزیز.
ساخت زبان برنامه نویسی فارسی یه سری مشکلات یا بهتره بگم نکات ریز برای خودم داشت که بی خیالش شدم
به نظرم غربی ها خیلی خوش شانس هستن از نظر ویژگی های زبانشون!
باید به نام گذاری متغیر ها فکر کنید
به بیوند با کتابخانه های خارجی هم همین طور
و مسایل ریز دیگه
مثلا این که باید کد برنامه خوانا باشه
دستورات و عملگر های ریاضی چه جوری باشه
...

----------


## l4dl4d

دوست عزیز کاظم فلاحی , با سلام
اینکار کار خیلی سختی نیست البته اینجوری:شما یک برنامه ی جاوا که تصاویر پازل یا مثلا اسلاید شو باشه رو تولید کنین
بعد نرم افزاری که مینویسید باید فایل جاوا رو باز کنه و تصاویری که کاربر انتخاب میکنه رو جایگزین کنه
اینجوری براحتی کارتون درست میشه
نرم افزار Fbook هم همچین کاری میکنه

----------


## jojoyejojo

> اکه سرعت براتون مهم نباشه فاز جلو بندی رو میتونید با هر زبانی پیاده سازی کنید ولی احتمالا تو فاز عقب بندی (به خاطر تولید کد ) نمیتونید روی هر زبانی حساب باز کنید.
> اگه شما با فازها و زیر فازهای کامپایلر و کاربردشون آشنا نیستید میتونم براتون توضیح بدم. من اطلاعاتم بیشتر در فاز جلوبندی هست. یعنی تا جایی که بتونید یه
> مفسر بنویسید.وقتی حرف از کاپایلر میشه معمولا شما باید بتونید برای سیستم عامل مورد نظر یه برنامه اجرایی تولید کنید.که من اطلاعات زیادی در این مورد ندارم. ولی در مفسر شما 
> فقط فاز جلوبندی و زیر شاخه های اونو دارید.و در آخر کد میانی تولید شده رو مستقیم اجرا میکنید.
> در کل فکر میکنم c یا ++c برای ایجاد کامپایلر مناسب باشه. ولی مفسر رو میتونید از هر زبانی استفاده کنید.البته باید به سرعت اجرا دقت کنید.



سلام.من این مطلب شمارو توآرشيو اينجا پيدا کردم و در حال حاضر برای درس کامپايلر بايد ی مفسر ساده بسازم
درواقع سوال استاد اين که ی فايل txt. بديم ب مفسر بعد ی فايل با ی زبان برنامه نويسی تحويل بگيريم که ترجيحا از خانواده C  باشه
می خواستم بدونم شما ميتونی کمک کنی؟

----------


## smhak16

من هستم،من حاضرم که باهم زبان برنامه نویسی جدید بسازیم ولی باید به من میل بدی!

smhak11@gmail.com

----------


## brightening-eyes

بچه ها, چه کاریه,
اینجا
رو ببینید, یه سری به آموزشاش بزنید, خیلی کارو راحت میکنه

----------


## arasahar

سلام دوستان هم وطن اگه پول درست حسابی تو کار هست من هستم چون هم علمش و هم حوصله اش را دارم من به عنوان یه نیمچه استاد ایرانی تو کشور خودم کسی نیست که بهمون بها بده ولی از سایر جاها بهم خیلی پیام میدن و اومدهاند به شهرمون و منو دیده اند و خواسته اند که با اونها کار کنم البته پس از امتحان اینو خواسته اند نه الکی من هم چون به پول نیاز دارم فکر میکنن که با اونها میرم ولی تا حالا استقامت کردهام پس اگه پول بدین میتونم باهاتون کار بکنم ببخشین ولی 
آنچه شیران را کند روبه مزاج 
احتیاج است احتیاج

----------


## arasahar

my mail is 
hacando60@gmail.com
please if u willl please call 
thanks a lotttttttttttttttttttttttttttt

----------


## one2015

سلام.
من می خوام برای زبان -c کامپایلر طراحی کنم.فاز scanner ,parser , semantic analyser نوشتم و درست کار میکنه این فازو نوشتم وقتی فایلهای خروجی رو کامپایل میکنم تا قبل از تابع yyparse() کار میکنه ولی بقیه اش تو console چاپ نمیشه یعنی خروجی نمیده لطفا کمک کنید.

----------


## mak12776

سلام.
من داشتم توی گوگل "برنامه نویسی open source" رو جستجو می کردم، که به این انجمن رسیدم و بعدا شانسی این پست رو پیدا کردم.

من پست آقای lamOverlord رو در اینجا خوندم که در مورد نوشتن یه نسخته جدید از VB نوشته بودند. و بیشتر بخش های این پست رو هم خوندم.

آقا منم هستم. اصلا خودم دارم سعی می کنم به زبان برنامه نویسی جدید بسازم به اسم Rest. سینتکسی (syntax) که برای Rest در نظر گرفتم می شه گفت تقریبا چیزی شبیه به VB هست. ولی من اصلا VB رو کار نکرده بودم و سینکس رو تاحالا ندیده بودم. و چیزی که من می خواستم بسازم یه ورژن دیگه از python بود که به C یا Assembly تبدیل بشه. من مشکلی که داشتم این بود که نوشتن برنامه توی C سخت بود چون که هی باید سمی کلن می زاشتم و حافظه برنامه رو به صورت دستی free و allocate می کردم. و نوشتن برنامه توی python راحت تره، ولی زمان اجرای برنامه بیشتر می شه. و برنامه بهینه نیست اصلا. کاری که من می خواستم بکنم این بود که یه زبان برنامه نویسی بسازم که سینتکسش در حد پایتون ساده باشه و به C تبدیل بشه و تمام بهینه سازی های لازم رو انجام بده. 

البته سینکسی که در نظر گرفتم از python راحت تره و دیگه مثل پایتون لازم نیست که همه جملات داخل یه بلاک با یه tab جلو بره، به جاش آخر هر بلاک یه end اضافه می کنیم. مثلا اگه تعریف کردن function توی python این شکلی باشه:


```
def sum(a, b):
    return a + b
```

چیزی که توی Rest در نظر گرفته بودم اینه:


```
def sum(a, b)
    return a + b
end
```

چندین تا زبان برنامه نویسی دیگه هم با سینتکس های ساده تر داره ساخته می شه، وجود دارند که اینا هستن: vlang, nim و crystal

nim تا یه حد خیلی زیادی جلو رفته و یه کتاب هم برای آموزشش نوشته شده، و به زبان C و javascript هم تبدیل می شه. ولی بهینه نمی شه. یا می شه گفت یه سری قابلیت براش در نظر گرفتن برای بهینه سازی، ولی بهینه سازی حداکثر رو انجام نمی ده. و می تونم بگم که می شه زبان برنامه نویسی نوشت که خیلی بهینه تر باشه.

crystal هم سینتکس خیلی ساده ای داره و مثل Ruby می مونه و به native byte code تبدیل می شه. سینتکسش رو هم یه نگاهی بکنید، بدک نیست.

vlang رو زیاد نخوندم در موردش ولی خیلی بهینه شده کامپایل می شه. و سینکس خیلی راحتی نداره.

ولی طرحی که من برای نوشتن Rest در نظر گرفتم، یه جوری در برگیرنده بیشتر ویژگی های زبان های برنامه نویسی بالا هست. یا شاید بشه گفت هر ویزگی که به نظرم خوب اومده رو توی نوشتن Rest در نظر گرفتم. البته در بعضی از قسمت هاش هنوز شک دارم، یا نوشتن بعضی از ایده ها خیلی وقت گیر خواهد بود. اما هنوز اول کارم، توی نوشتن مرحله Tokenizer ام. نمی دونم شما بهش می گید مترجم معنوی یا لغوی، ولی اینجا می تونید پیدا کنید که منظورم چی هست.

نمی دونم که می تونیم باهم هم کاری داشته باشیم یا نه، یا اصلا اسم زبانی که می خوایم بسازیم رو، چی بزاریم. ولی من آماده همکاری هستم اگه ایده و نظری دارید بگید که با هم گفت و گو کنیم. و در ضمن اسم Rest رو برای این انتخاب کردم که انگاری که استراحت برنامه نویس ها باشه. بشه توی یه سینتکس ساده برنامه نویسی کرد و به بهترین شکل ممکن بهینه بشه.  :متفکر:  البته هنوز ایده است تا به پروژه کامل برسه.  :چشمک: 

اینجا می تونید سورس Rest رو که دارم می نویسم ببنید. و اینجا هم می تونید طرحی که در نظر گرفتم رو ببنید. اگه چیزی رو متوجه نشدید بگید که توضیح بدم.

و یه پیشنهاد دارم توی پست هاتون رو که می خوندم:
بین FASM و MASM شک داشتید که به کدوم کامپایل بشه، به نظر من به NASM کامپایل بشه بهتره. چون که اولا NASM خیلی معروف تره و افراد بیشتری روش کار کردند و open source هم هست، و هم به خاطر این که هم برای ویندوز و هم برای لینوکس کامپایل می کنه. ولی MASM برای لینوکس کامپایل نمی کنه، open source هم نیست و FASM هم به اندازه NASM پیشرفته نیست. یه اسمبلر دیگه هم وجود داره به اسمه GAS که وقتی C یا Cpp می خود کامپایل بشه به اون تبدیل می شه، ولی اصلا راحت نیست و بیشتر برای C ساخته شده. یه راه حل دیگه هم وجود داره اونم اینه که از library هایی که برای تولید byte code استفاده می شه، بهره ببرید که بستگی به این داره که با کدوم راحت تر باشید.

منتظر نظرتون هستم.

----------

