شنبه ۶ خرداد ۱۳۹۶
 
 
 
کلمه عبور خود را فراموش کرده اید؟
 

 
 
 آموزش نوشتن Parser با VeParser
.NET C#
تاریخ ثبت:  ۹۰/۷/۲۳
تعداد نمایش:  ۷۳۵۴
  نویسنده: سام ناصری
 
   ۷  نفر تا این لحظه به این مقاله امتیاز داده اند.
 
   Bookmark and Share

مقدمه

شاید بارها برای شما پیش آمده باشد که بخواهید یک فایل با یک فرمت خاص را بخوانید، یا اینکه ایده ای درباره طراحی یک زبان برنامه نویسی داشته باشید اما در نخستین گام با چالش تبدیل متن به ساختار داده یعنی Pars کردن روبرو شده باشید و بعد از مدتی بررسی کتابخانه های مختلف و رویارویی با انبوه مفاهیم و واژگان پیچیده در حوزه طراحی و پیاده سازی Parser، کامپایلر و گرامرها از خیال خود چشم پوشی کرده باشید. VeParser کتابخانه ای است که به شما اجازه میدهد که بدون داشتن دانش فنی در حوزه Parserها و کامپایلرها و حتی گرامر برای زبان مورد نظر خود Parser بنویسید و یا یک فایل با یک ساختار خاص را پردازش کرده و تبدیل به ساختاری از اشیا بکنید.


VeParser چیست؟

VeParser یک کتابخانه رایگان است که با استفاده از آن میتوانید Parser تولید کنید. جهت کسب اطلاعات بیشتر میتوانید به آدرسهای زیر مراجعه کنید:



موارد کاربرد VeParser

VeParser را میتوانید برای موارد زیر بکار ببرید:

  • پردازش یک فایل نظیر فایلهای csv، xml یا bmp یا هر فایل دیگری که از یک ساختار خاص بهره میبرد.
  • طراحی یک Parser برای یک زبان موجود نظیر #C
  • طراحی یک Parser برای یک زبان جدید
  • در تمام موارد فوق Parser شما میتواند همزمان با تجزیه کردن ورودی ساختارهای اشیای خروجی را نیز تولیدی کند.


آنچه  باید داشته باشید
VeParser وابستگی به هیچ کتابخانه دیگری ندارد و تنها به موراد زیر برای استفاده از آن نیاز دارید:

  • دات نت فریم ورک 4
  • ویژوال استودیو (از لحاظ تئوری لازم نیست، ولی عملاً لازم است)

آغاز کار با کتابخانه و پارسر
VeParser در قالب یک کتابخانه تحت عنوان veparser.dll در اختیار شما است.
با استفاده از nuget دستور زیر را در پروژه خود وارد کنید:

PM> Install-Package veparser

یا اگر از nuget استفاده نمیکنید مراحل زیر را پی بگیرید:

  1. به آدرس پروژه بروید: http://veparser.codeplex.com
  2. به صفحه Downloads بروید
  3. Binary را دانلود کنید و در مسیر دلخواه خود کپی کنید.
  4. در پروژه خود در ویژوال استودیو به فایل veparser.dll که دانلود کرده اید یک رفرنس(Reference) اضافه کنید.


آغاز نوشتن یک Parser با VeParser

برای نوشتن یک Parser جدید با VeParser کافی است مراحل زیر را پی بگیرید. (در ادامه توضیح هر مرحله را ارائه میدهم): 

  1. یک کلاس جدید به پروژه اضافه کنید و آن را از کلاس VeParser.BaseParser یا VeParser.TokenParserمشتق کنید.
  2. متود GetRootParser را override کنید.
  3. در متود GetRootParser پارسر زبان خود را ترکیب کنید و به عنوان خروجی برگردانید.
  4. در صورتی که در مرحله یک از TokenParser استفاده کرده باشد.
    1. از Lexer.Parse برای تبدیل متن ورودی به لیست token ها استفاده کنید.
  5. Parser شما آماده است متود BaseParser.Parse را با متن ورودی یا لیست token ها فراخوانی کنید.

 

اضافه کردن کلاس Parser به پروژه

در گام اول شما باید یک کلاس از یک کلاس VeParser.BaseParser یا VeParser.TokenParser مشتق کنید،

مشتق کردن از کلاس پایه BaseParser

کلاس BaseParser یک پارامتر جنریک دارد که در هنگام مشتق کردن از آن بایستی آن را ست کنید. این پارامتر نوع داده های ورودی را تعیین میکند برای پردازش یک متن  نوع char قاعدتاً باید انتخاب شود(یک متن آرایه ای از کاراکترها است.)

public class CSVParser : VeParser.BaseParser<char>
{
         
}

مشتق کردن از کلاس پایه TokenParser

کلاس TokenParser خود از کلاس BaseParser<token> مشتق شده است، پس این کلاس در ورودی خود لیستی از نوع VeParser.token را دریافت میکند. در آینده در مقاله ای جداگانه توضیح میدهم که چگونه با استفاده از کلاس Lexer میتوانید با دادن کلمات کلیدی و سمبولهای زبان خود یک متن ورودی را به لیستی از token ها پارس کنید. بعد از اینکه ورودی را با استفاده از Lexer تبدیل به لیست token کردید، بقیه مراحل مشابه استفاده از کلاس پایه BaseParser است.


پیاده سازی بدنه Parser

کلاس BaseParser پایه ای ترین کلاس تعریف شده در کتابخانه VeParser است. در این کلاس یک متود abstract به نام GetRootParser تعریف شده است که شما بایستی آن را پیاده سازی کنید. این متود بدنه اصلی Parser شما خواهد بود.

public class CSVParser : VeParser.BaseParser<char>
{
    protected override VeParser.Parser GetRootParser()
    {
        throw new System.NotImplementedException();
    }   
}


ترکیب Parser ها با یکدیگر جهت ساختن بدنه Parser

Parser یعنی چه؟

تا اینجای داستان قضایا ساده بود، از اینجا به بعد باید کمی دقت کنید، Parser در VeParser یک مفهوم عینی است نه عنوانی کلی برای فرایند تجزیه کردن. منظورم این است که در VeParser ما یک delegate type به نام Parser داریم که وقتی اجرا میشود مشخص میکند تجزیه موفق بوده است یا خیر.

ترکیب یعنی چه؟

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


ترکیب کننده چیست؟

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


نمونه نهایی

برای نمونه کد زیر نشان میدهد که چگونه با VeParser میتوانید یک Parser برای فایلهای csv بنویسید:

public class CSVParser : VeParser.BaseParser<char>
{
    protected override VeParser.Parser GetRootParser()
    {
        return zeroOrMore(deleimitedList(toParser(ch => ch == ','), toParser(char.IsLetterOrDigit)));
    }   
}


ادامه داستان ...

این مقاله صرفاً جهت یک معرفی کلی از VeParser است، Veparser قابلیت های بیشتری از تجزیه کردن ورودی دارد و در یک مقاله نمیتوان تمام ویژگی های آن را توضیح داد. پس به زودی با مقالاتی درباره نوشتن Parser های قویتر، معرفی ترکیب کننده ها، آموزش نحوه اشکال زدایی از گرامر Parser، پایش اجرای فرایند تجزیه، نحوه تولید AST یا همان نتیجه پردازش و مقالاتی دیگر اطلاعات بیشتری در اختیار شما قرار خواهم داد.



بازخورد و پیشنهاد

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

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

 عنوان فرستنده تاریخ
 
تشكر + نظر ابوالفضل حسن الدين ۱۳۹۰/۷/۲۵
پاسخ به: تشكر + نظر سام ناصری ۱۳۹۰/۷/۲۵
پاسخ به: تشكر + نظر ابوالفضل حسن الدين ۱۳۹۰/۷/۲۵
پاسخ به: تشكر + نظر سام ناصری ۱۳۹۰/۷/۲۸
اولین قبلی بعدی

Copyright © 2006 - 2016 All Rights Reserved.
Please direct your questions or comments to