مفسر یک زبان سادٌ در هسکل دس ایي پشٍطُ بب استفبدُ اص دادُّبی جبشی قسوتّبی هختلف یک هفسش بشای یک صببى سبدُ عشاحی خَاّذ ضذ .بشای ایيکبس ابتذا سضتِّبی هتي بشًبهِ ببیذ تَسظ یک lexical analyzerبِ لیستی اص تَکيّب تبذیل ضًَذ .سپس یک پبسسش تَکيّب سا گشفتِ ٍ اص سٍی آىّب یک abstract syntax treeبسبصد .دس ًْبیت یک هفسش ASTسا گشفتِ ٍ آى سا اجشا هیکٌذ .دس ایي پشٍطُ بشای پیبدُسبصی پبسسش اص یک سشی اپشاتَسّبی تبذیل پبسسشّب استفبدُ هیکٌین کِ بِ آىّب تشکیبگش پبسسشّب گفتِ هیضَد. هطخعکشدى دستَسّبی صببى بب استفبدُ اص AST غَست کلی دستَسّبی صببى بِ ضکل صیش است. یک assignmentکِ ضبهل دٍ قسوت هختلف خَاّذ بَد: .1یک هتغیش کِ قشاس است هقذاس دس آى رخیشُ ضَد. .2یک ػببست کِ هقذاس هَسدًظش سا هطخع هیکٌذ یک sequenceکِ ضبهل دٍ قسوت خَاّذ بَد: .1یک دستَس کِ قشاس است اٍل اجشا ضَد. .2یک دستَس کِ قشاس است بؼذ اص دستَس اٍل اجشا ضَد. یک conditionalکِ ضبهل سِ قسوت خَاّذ بَد: .1یک ػببست کِ هطخعکٌٌذُی هقذاسی است کِ ببیذ تست ضَد. .2یک دستَس کِ دس غَست دسست بَدى ػببست ببیذ اجشا ضَد. .3یک دستَس کِ دس غَست غلظ بَدى ػببست ببیذ اجشا ضَد. یک loopکِ ضبهل دٍ قسوت خَاّذ بَد: .1یک ػببست کِ هطخع هیکٌذ ػولیبت تب چِ صهبًی ببیذ اجشا ضَد. Parser Combinators 1 .2یک دستَس کِ تب صهبًی کِ ػببست دسست ببضذ ببیذ اجشا ضَد. While X>Y Do ;X := X-1 Z := Z*Z End غَست کلی دستَسّبی صببى ًحَُی پیبدُسبصی abstract syntax treeسا بِ ػٌَاى یک دادُی ببصگطتی بشای هب هطخع هیکٌذ .ایي دادُ کِ بب ًبم Commandهطخع خَاّذ ضذ حبلتّبی هختلف یک abstract syntax treeبشای دستَسّبی صببى هَسدًظش سا پیبدُسبصی خَاّذ کشد .بشای ایي کبس فشؼ کٌیذ کِ یک دادُ بب ًبم Exprبشای ًوبیص ػببستّب ٍ یک دادُ بب ًبم Variableبشای ًوبیص هتغیشّب دس صببى تؼشیف ضذُاًذ .تؼشیف دادُی Commandبب استفبدُ اص اعالػبت دادُضذُ دس هَسد دستَسّب اًجبم هیضَد. = see later type Variable = see later type Expr ________ ________ type Command = Assign ________ ________ | Seq ________ ________ ________ | Cond ________ ________ | While deriving Show ایي تؼشیف چْبس سبصًذُ بشای چْبس حبلت هختلف ّش دستَس ایجبد هیکٌذ. ________ Assign :: ________ :: Seq ________ :: Cond ________ While :: تمریه ايل: تؼشیف دادُضذُ بشای دادُی Commandسا کبهل کٌیذّ .نچٌیي تبیپ سبصًذُّب سا هطخع ًوبییذ. بب تَجِ بِ تؼشیف دادُضذُ اص Commandهثبلی ضکل قبل سا هیتَاى بِ غَست صیش هطخع کشد: Constructor 2 ))While e (Seq (Assign v1 e1) (Assign v2 e2 دقت کٌیذ کِ دس ػببست ببال e2 ٍ e1 ،eهتغیشّبیی ًطبىدٌّذُی ػببستّب ٍ v2 ٍ v1هتغیشّبیی ًوبیصدٌّذُی هتغیشّبی Z ٍ X ّستٌذ. بشای کبهل کشدى تؼشیف ببال ببیذ ػببستّبی استفبدُضذُ دس صببى سا تؼشیف کٌیذ .بشای سبدگی فشؼ هی کٌین کِ ػببستّبی صببى اص ثببتّبی غحیح ،هتغیشّب ٍ سِ ػولگش دٍدٍیی ،یؼٌی ،Greater ٍ Times ،Minusسبختِ ضذُاًذ .بشای ًوبیص هتغیشّب اص سضتِی سبدُ استفبدُ هیکٌین ،یؼٌی بشای ًوبیص هتغیش Xاص سضتِی ” “Xاستفبدُ خَاّین کشدّ .نچٌیي فشؼ هیکٌین کِ ًتیجِی ّش ػببست یک ػذد غحیح است ٍ بشای ػببستّبی هٌغقی دسست اص ٍ 1بشای ػببستّبی هٌغقی غلظ اص 0استفبدُ هیکٌین .بِ ایي تشتیب بِ تؼشیفّبی صیش خَاّین سسیذ: type Variable = String type Val = Int data Expr = Const Val | Var Variable ________ ________ | Minus ________ ________ | Times ________ ________ | Greater deriving Show تمریه ديم :تؼشیف دادُی Exprسا کبهل کٌیذ. بب تَجِ بِ تؼشیف هطخعضذُ اص دادُی Exprهیتَاى ASTهشبَط بِ کذ قبل سا بِ غَست کبهل ًَضت: ))”While (Greater (Var “X”) (Var “Y )))(Seq (Assign “X” (Minus (Var “X”) (Const 1 ))))”(Assign “Z” (Times (Var “Z”) (Var “Z دقت کٌیذ کِ بب اًجبم تغییشات الصم دس دادُّبی Command ٍ Variable ،Exprهیتَاى سبختبس ّش صببًی سا پیبدُسبصی کشد. هقذاس ػببستّب ٍ ّStoreب دقت کٌیذ کِ هحبسبِی هقذاس ػببستّب ٍابستِ بِ هقبدیشی است کِ دس هتغیشّب رخیشُ ضذُاست .بشای فْویذى ٍضؼیت کًٌَی هتغیشّب اص Storeاستفبدُ هیکٌین .دقت کٌیذ کِ ّCommandب ّویطِ ًسبت بِ یک Storeخبظ اجشا خَاٌّذ ضذ .بشای ایي کبس هب یک تبیپ جذیذ Storeهؼشفی خَاّین کشد .کبسّبی اٍلیِای کِ بش سٍی یک Storeاًجبم خَاّذضذ بِ غَست صیش است ٍ بقیِی کبسّب بِ ٍسیلِی ایي ۳ػولیبت قببل پیبدُسبصی خَاٌّذ بَد. :: Store -> Variable -> Val fetch update :: Store -> Variable -> Val -> Store :: Store تببغ fetchهقذاس اختػبظ دادُضذُ بِ هتغیش ٍسٍدی دس initial Storeهَسد ًظش سا ببصهیگشداًذ .تببغ updateیک Storeجذیذ ایجبد هیکٌذ کِ کبهال ضبیِ ٍ Storeسٍدی است بب ایي تفبٍت کِ ٍضؼیت هتغیشی کِ بب ٍسٍدی دٍم هطخع هیضَد بِ هقذاسی کِ بب ٍسٍدیی سَم هطخع هیضَد بِسٍص خَاّذ ضذّ .نچٌیي Storeپیصفشؼ کِ بب initialهطخع ضذُاست هقذاس 0سا بب ّوِی هتغیشّب هتٌبظش خَاّذ کشد. دس هَسد تؼشیف Storeبؼذا غحبت خَاّذ ضذ. پیذا کشدى هقذاس ػببستّب بب تَجِ بِ قبًَىّبی دستَسی صببى هیتَاى بِ ّش ػببست یک هقذاس اختػبظ داد .بِ ػببست دیگش بش خالف دستَسّب کِ تؼشیفکٌٌذُی یک ػولیبت ّستٌذ ،ػببستّب تؼشیفکٌٌذُی هحبسببتی ّستٌذ کِ دس ًْبیت بِ یک هقذاس هٌتْی خَاّذ ضذ .بشای پیذاکشدى هقذاس ػببستّب هیتَاى اص تببغ صیش استفبدُ کشد. eval :: Expr -> Store -> Val ایي تببغ یک ػببست ٍ یک Storeگشفتِ ٍ هقذاس ػببست دادُضذُ ًسبت بِ Storeدادُضذُ سا هحبسبِ هیکٌذ. هقذاس یک ػببست ثببت هستقل اص Storeهطخع است .اص عشف دیگش هقذاس یک هتغیش سا بب استفبدُ اص تببغ fetchهیتَاى بِ دست آٍسد .بشای بِ دست آٍسدى هقذاس ػببستّبیی کِ اص اپشاتَسّبی دٍدٍیی استفبدُ هیکٌٌذ ببیذ ابتذا هقذاس ّش یک اص ػولًٍذّب سا بِ دست آٍسدُ ٍ سپس بب تَجِ بِ آىّب هقذاس ًْبیی سا هحبسبِ کشد. تمریه سًم: بب تَجِ بِ تَضیحبت ببال تببغ evalسا پیبدُسبصی کٌیذ. تفسیش کشدى دستَسّب حبل کِ هیتَاًین هقذاس ػببستّب سا پیذا کٌین تَاًبیی اجشای دستَسّب سا ًیض خَاّین داضت .بشای تفسیش دستَسّب اص تببغ صیش استفبدُ هیکٌین. interpret :: Command -> Store -> Store ایي تببغ Storeبِ دست آهذُ اص اجشای دستَس دادُضذُ ًسبت بِ Storeدادُضذُ سا ببصهیگشداًذ .بِ ػببست دیگش هیتَاًیذ ایي تببغ سا بِ ػٌَاى تببؼی دس ًظش بگیشیذ کِ بب گشفتي یک دستَس یک ػولگش بش سٍیّStoreب ببصهیگشداًذ. سبدُتشیي دستَس ایي صببى دستَس Assignاست .ایي دستَس ببیذ بب ایجبد تغییشات جضئی دس ٍ Storeسٍدی هقذاس هتغیش هطخعضذُ سا بِ هقذاسی کِ اص ػببست هشبَط بِ دستَس بِ دست هیآیذ تغییش دّذ .بشای ایيکبس ببیذ اص تببغ updateاستفبدُ کٌین. تمریه چهارم: بب تَجِ بِ تَضیحبت ببال ،قسوتی اص تؼشیف تببغ interpretسا کِ هشبَط بِ اجشای دستَسّبی سبختِ ضذُ بب Assignاست بٌَیسیذ. بشای اجشای دستَسّبی پطت سش ّن ببیذ دستَسّب سا بِ تشتیب ًسبت بِّStoreبی هٌبسب اجشا کٌین. تمریه پىجم: قسوتی اص تؼشیف interpretکِ هشبَط بِ اجشای دستَسّبی سبختِضذُ بب ّ Seqستٌذ سا پیبدُسبصی کٌیذ .دقت کٌیذ کِ ّش قسوت اص ایي دستَس سا ًسب بِ چِ Storeی ببیذ اجشا کٌین. بشای اجشای حلقِّب یب دستَسّبی ضشعی ببیذ ابتذا هقذاس ػببست ضشعی سا پیذا کشدُ ٍ بب تَجِ بِ هقذاس آى دستَسّبی هختلفی سا اجشا کٌین .بشای ایيکبس اص تببغ صیش استفبدُ هیکٌین. switch :: Val -> (Store -> Store) -> (Store -> Store) -> Store -> Store ایي تببغ ببیذ بب تَجِ بِ هقذاس دادُضذُ یکی اص ػولگشّبی دادُضذُ سا بش سٍی Storeدادُضذُ اجشا کٌذ( .دقت کٌیذ کِ ٍسٍدیّبیی کِ اص ًَع ّ Store -> Storeستٌذ دس ٍاقغ ػولگشّبیی بش سٍی ّ Storeستٌذ). تمریه ششم: تببغ switchسا پیبدُسبصی کٌیذّ .نچٌیي بب استفبدُ اص ایي تببغ قسوتی اص تببغ interpretسا کِ هشبَط بِ اجشاکشدى دستَسّبی بِ فشم Condاست بٌَیسیذ. بشای یک حلقِ ػولیبتّبی هوکي اًجبم دادى ػولیبت هَجَد دس حلقِ ٍ اًجبم دٍببسُی حلقِ دس غَست 1بَدى هقذاس تست ٍ ّیچکبسی اًجبمًذادى دس غَست 0بَدى هقذاس تست خَاّذ بَد. تمریه هفتم :تببغ interpretسا بشای دستَسّبیی کِ بب Whileسبختِ ضذُاًذ بٌَیسیذ. ًوبیص ّStoreب ّش Storeدادُسبختبسی است کِ بِ هتغیشّب هقذاس هتٌبظش آىّب سا ًسبت هیدّذ .دس ٍاقغ یک Storeتببؼی اص فضبی هتغیشّب بِ فضبی هقذاسّب است .بٌببشایي بشای ًوبیص ّStoreب اص یک تبیپ تببؼی استفبدُ هیکٌین. type Store = Variable -> Val ّوبىعَس کِ گفتِ ضذ initialیک Storeاست کِ بِ ّوِی هتغیشّب هقذاس 0سا ًسبت هیدّذ .تببغ fetchتببؼی است کِ بب گشفتي یک هتغیش ٍ یک Storeهقذاس ًسبت دادُضذُ بِ آى هتغیش دس Storeدادُضذُ سا ببصهیگشداًذ .تببغ updateتببؼی است کِ یک Storeگشفتِ ٍ Storeجذیذی ببصهیگشداًذ کِ دس آى هقذاس ٍ هتغیش جذیذ قشاس دادُضذُاًذ. تمریه هشتم: بب تَجِ بِ ًکتِّبی گفتِضذُ تببغّبی update ٍ fetch ،initialسا پیبدُسبصی کٌیذ .دقت کٌیذ کِ پیچیذگی ػولیبتّب ببیذ ًسبت بِ تؼذاد هتغیشّب خغی ببضذ. بب پیبدُسبصی ایي تَابغ ضوب هیتَاًذ تببغ interpretخَد سا بش سٍی هثبلی کِ اص یک دستَس صدین اهتحبى کٌیذ: ))”interpret (While (Greater (Var “X”) (Var “Y )))(Seq (Assign “X” (Minus (Var “X”) (Const 1 (Assign “Z” (Times (Var “Z”) (Var “Z”))))) initial ًحَُی کبس پبسسش حبل کِ ًحَُی تفسیش ّ ASTب سا پیبدُسبصی کشدُاین ببیذ تَابغ هشبَط بِ خَاًذى تَکيّب ٍ تبذیل آىّب بِ ASTسا پیبدُسبصی کٌین .ایي تَابغ بب استفبدُ اص تکٌیکّبی ًَ higher-order programmingضتِضذُ ٍ بِ ساحتی بشای ًَضتي پبسسش صببىّبی دیگش ًیض قببل تغییش ٍ استفبدُ خَاٌّذبَد. بشای ایيکبس ابتذا ببیذ یک دادُ بشای ًوبیص تَکيّب هطخع کٌین. data Token = Ident String | Symbol String | Number Int بب استفبدُ اص ایي دادُ هیتَاًین قسوتّبی هختلف صببى بشًبهًَِیسی یؼٌی اػذادً ،وبدّبی صببى ٍ ّindetifierب سا هذلسبصی کٌین .بشای هثبل کذی کِ دس قسوتّبی قبل بشسسی ضذ یؼٌی ”“While X > Y Do X := X – 1; Z := Z * Z End پس اص اًجبم lexical analysisبِ غَست لیستی اص تَکيّب دس خَاّذ آهذ: *Symbol “While”, Ident “X”, Symbol “>”, Ident “Y”, Symbol “Do”, Ident “X”, Symbol “:=”, Ident “X”, Symbol “-“, Number 1, Symbol “;”, Ident “Z”, Symbol “:=”, Ident “Z”, Symbol “*”, Ident “Z”, Symbol “End”+ ٍظیفِی تببغ parseتبذیل ایي لیست اص تَکيّب بِ یک ASTاست .ایي تببغ ببیذ Commandی کِ تَسظ لیست تَکيّب ًوبیصدادُ هیضَد سا ببصگشداًذ .بِ ػببست دیگش ایي تببغ ببیذ اص لیست تَکيّبی دادُضذُ دس ببال Commandصیش سا ایجبد کٌذ: ))”While (Greater (Var “X”) (Var “Y )))(Seq (Assign “X” (Minus (Var “X”) (Const 1 ))))”(Assign “Z” (Times (Var “Z”) (Var “Z بشای ًَضتي یک پبسسش بشای ّ Commandب هب ببیذ بشای قسوتّبی هختلفی کِ ایي دستَسات سا تطکیل هیدٌّذ پبسسش عشاحی کٌین، بشای هثبل بشای ػببستّبّassignment ،بّconditional ،ب ٍ غیشُ .بشای ایيکِ بتَاًین ضکستخَسدى ػولیبت سا هطخع کٌین تببغّبی پبسسش ببیذ یک دادُ اص ًَع Maybeببصگشداًٌذّ .نچٌیي چَى ّشتببغ لضٍهب ّوِی تَکيّبی دادُضذُ سا ًویخَاًذ تَکيّبی ببقیهبًذُ ًیض تَسظ تببغ ببصگشداًذُ خَاٌّذضذ .بِ ایي تشتیب هیتَاى typeیک پبسسش بشای یک هتغیش کلی ( aکِ هیتَاًذ ّشچیضی هبًٌذ Commandیب Exprیب Intببضذ) بِ غَست صیش خَاّذ بَد: )]type Parser a = [Token] -> Maybe (a, [Token گشاهش دقیق صببى بشًبهًَِیسی حبل کِ هیخَاّین بشای تَکيّبی صببى پبسسش بٌَیسین ًیبص داسین کِ گشاهش دقیق ٍ کبهل صببى سا هؼشفی کٌین .بشای هؼشفی گشاهش اص چٌذ قبػذُ دس هؼشفی گشاهشّب کوک هیگیشین: .1سضتِّبی قشاس گشفتِضذُ دس ”“ ببیذ بِ غَست لفظی دس سضتِ ٍجَد داضتِ ببضٌذ. .2قسوتّبی اختیبسی (یؼٌی قسوتّبیی کِ هیتَاًٌذ ٍجَد داضتِببضٌذ یب ٍجَد ًذاضتِببضٌذ) دس][ قشاس دادُ خَاٌّذ ضذ. .3 دس غَستی کِ یک هتغیش چٌذ حبلت داضتِ ببضٌذ ایي حبلتّب بب استفبدُ اص| هطخع خَاٌّذ ضذ. بب تَجِ بِ ایي قَاػذ گشاهش صببى سا بِ غَست صیش هؼشفی هیکٌین: ]aexp *“>” aexp >= exp ]bexp *“-“ aexp >= aexp ]cexp *“*” bexp >= bexp “(“ exp “)” | number | variable >= cexp ]unitcom *“;” command >= command whilecom | ifcom | assign >= unitcom ”“While” exp “Do” command “End >= whilecom ”“If” exp “Then” command “Else” command “EndIf >= ifcom variable “:=” exp >= assign تشکیبگش پبسسشّب حبل بِ هسبلِ ًَضتي پبسسشّب بشهیگشدین .هیخَاّین بشای قسوتّبی هختلف صببى پبسسش بٌَیسین .بشای استفبدُ اص هفبّین بشًبهًَِیسی بِ غَست higher-order programmingببیذ تالش کٌین کِ ببیٌین چغَس هیتَاًین اص سٍی پبسسشّبی قسوتّبی کَچکتش بشای قسوتّبی بضسگتش پبسسش بسبصین .البتِ دس ًْبیت ًیبص بِ ایجبد چٌذ پبسسش اٍلیِ خَاّین داضت ،اهب ّوِی پبسسشّبی پیچیذُتش اص سٍی ایي چٌذ پبسسش اٍلیِ سبختِ خَاٌّذضذ .بشای هثبل یک پبسسش بشای ً assignmentیبص داسد کِ ابتذا یک هتغیش پیذا کشدُ سپس ًوبد ”= “:سا پیذا کشدُ ٍ دس ًْبیت یک ػببست پیذا کٌذ .دس ًتیجِ پبسسش هشبَط بِ assignmentسا هیتَاى اص سٍی پبسسشّبی هشبَط بِ هتغیش ،هشبَط بِ ”= ٍ “:هشبَط بِ ػببست ًَضت .بشای ایيکبس تؼذادی تشکیبگش پبسسش تؼشیف هیکٌین کِ بب استفبدُ اص آىّب هیتَاًین پبسسشّبی سبدُتش سا بب ّن تشکیب کٌین. اگش یک تشکیبگش >&< (بخَاًیذ «ٍ سپس») تؼشیف کٌین کِ دٍ پبسسش سا تشکیب کشدُ ٍ پبسسش جذیذی کِ اص اجشای آى دٍ پبسسش بؼذ اص یکدیگش بِ ٍجَد هیآیذ سا ببصگشداًذ هیتَاًین تؼشیف دادُضذُ بشای assignmentسا پیبدُسبصی کٌین .فشؼ کٌیذ کِ پبسسشّبی اٍلیِی صیش هَجَد ببضٌذ: :: Parser Variable variable :: Parser Expr exp :: String -> Parser String literal بِ ایي تشتیب هیتَاًین پبسسش هشبَط بِ assignmentسا بِ غَست صیش بٌَیسین: Variable <&> literal “:=” <&> exp ّنچٌیي بشای هفَْم «یب» (کِ ّوبى | دس تؼشیف گشاهش است) یک تشکیبگش >|< سا هؼشفی هیکٌین کِ پبسسش حبغل اص ایي تشکیبگش ابتذا پبسسش اٍل سا اهتحبى کشدُ ٍ سپس پبسسش دٍم سا اهتحبى هیکٌذ .هثال هیتَاًین بٌَیسین: Assign <|> whilecom <|> ifcom ایي پبسسش دس غَست هَفق بَدى یب یک assignmentپیذا هیکٌذ یب یک whilecomپیذا هیکٌذ ٍ یب یک ifcomپیذا هیکٌذ .دس غَستی کِ ّیچکذام اص آىّب پیذا ًطًَذ پبسسش ضکست خَسدُ است. بِ typeایي تشکیبگشّب دقت کٌیذ: <|> :: Parser a -> Parser a -> Parser a )<&> :: Parser a -> Parser b -> Parser (a,b دس ایيجب بِ یک تشکیبگش هْن دیگش ًیبص داسین کِ بِ هب اجبصُ هیدّذ ًتیجِی ببصگشداًذُضذُ اص یک پبسسش سا تغییش دّین .بشای هثبل دقت کٌیذ کِ هقذاس حبغل اص هَفقضذى یک پبسسش کِ بب >&< سبختِضذُ است یک صٍج اص هقبدیش ببصگشداًذُضذُ تَسظ قسوت اٍل پبسسش ٍ قسوت دٍم پبسسش خَاّذ بَد ،دس حبلی کِ هب احتوبال ًیبص داسین آى سا بِ typeدیگشی تغییش دّین .ایي تشکیبگش سا modify هیًبهین .بشای هثبل دقت کٌیذ کِ پبسسش صیش variable <&> literal “:=” <&> exp دس ٍاقغ اص ًَع )) Parser (Variable, (String, Exprاست .دس حبلی کِ هب اًتظبس داسین ایي پبسسش بشای هب ّassignmentب سا ببصگشداًذ ،یؼٌی هقبدیشی اص ًَع .Commandبشای ایي کبس تببؼی بشای تبذیل هقبدیش ببصگشداًذُضذُ تَسظ ایي پبسسش بِ هقذاس هَسد ًظش خَد هیًَیسین: mkAssignNode :: (Variable, (String, Expr)) -> Command mkAssignNode (v, (s, e)) = Assign v e حبل بب استفبدُ اص ایي تببغ ٍ تشکیبگش modifyهیتَاًین پبسسش هشبَعِ بِ assignmentسا بِ عَس کبهل پیبدُسبصی کٌین: assign = (variable <&> literal “:=” <&> exp) `modify` mkAssignNode ٍ اکٌَى assignیک پبسسش اص ًَع Parser Commandاست ،یؼٌی ّوبىچیضی کِ اًتظبس داسین. دس صیش ّشیک اص تشکیبگشّب سا ضشح هیدّین .لغفب دٍببسُ تؼشیف Parser aسا هغبلؼِ کٌیذ ٍ دقت کٌیذ کِ ّش Parser aدس غَست ضکست یک ٍ Nothingدس غَست هَفقیت یک ) Just (v,lstببص هیگشداًذ کِ دس آى vهقذاس parseضذُ تَسظ ( parserیؼٌی هقذاسی اص ًَع lst ٍ )aلیست ببقیهبًذُی تَکيّب است. پبسسشی کِ بِ غَست parser1 <|> parser2سبختِ هیضَد ابتذا parser1سا بش سٍی لیست تَکيّب اهتحبى هیکٌذ .دس غَستی کِ ایي پبسسش هَفق ببضذ هقذاس ببصگشداًذُضذُ تَسظ آى سا ببصهیگشداًذ .اهب دس غَستی کِ ایي پبسسش ضکست بخَسد parser2سا بش سٍی لیست ٍسٍدی اجشا کشدُ ٍ ًتیجِ سا ببصهیگشداًذ .بِ ایي تشتیب اگش ّش دٍ قسوت ایي پبسسش ضکست بخَسًذ (بِ ػببست دیگش Nothing ببصگشداًٌذ) کل پبسسش ًیض ضکست هیخَسد ٍ Nothingببص هیگشداًذ. پبسسشی کِ بِ غَست parser1 <&> parser2سبختِ هیضَد ابتذا parser1سا بش سٍی لیست ٍسٍدی اجشا هیکٌذ .دس غَستی کِ ایي پبسسش ضکست خَسدُ ببضذ کل ػولیبت ضکست خَسدُاست ٍ Nothingببصگشداًذُ هیضَد .اهب دس غَست هَفقبَدى ایي پبسسش ببقیهبًذُی لیست تَکيّب بِ parser2دادُ هیضَد تب قسوت بؼذی ایي پبسسش ًیض اًجبم ضَد .اگش parser2ضکست بخَسد ببص ّن کل ػولیبت ضکست خَسدُ ٍ Nothingببصگشداًذُ هیضَد .اهب دس غَستی کِ ً parser2یض هَفق ببضذ هقذاس پبسسضذُ تَسظ ایي دٍ پبسسش دس قبلب یک صٍج هشتب بِ ّوشاُ ببقیهبًذُی لیست تَکيّب بؼذ اص اجشای parser2ببصگشداًذُ هیضَد (بِ تؼشیف Parser aدقت کٌیذ). پبسسشی کِ بِ غَست parser1 `modify` fسبختِ هیضَد ابتذا parser1سا بش سٍی لیست ٍسٍدی اجشا هیکٌذ .دس غَستی کِ ایي پبسسش ضکست بخَسد کل ػولیبت ضکست خَسدُ ٍ Nothingببصگشداًذُ هیضَد .اهب دس غَست هَفقیت آهیض بَدى ػولیبت parser1 تببغ fبش سٍی هقذاسّبی پبسسضذُ تَسظ ایي پبسسش اجشا ضذُ ٍ هقذاس بِ دستآهذُ بِ ّوشاُ ببقیهبًذُ لیست تَکيّب ببصگشداًذُ هیضَد. ّنچٌیي دٍ پبسسش اٍلیِ ًیض کِ هَسد ًیبص است دس اختیبس ضوب قشاس هیگیشد. اٍل ] emptyseq :: Parser [aاست کِ ّویطِ هَفق هیضَد صیشا بِ دًببل لیست خبلیای اص تَکيّبست ٍ ّیچ تَکٌی سا استفبدُ ًویکٌذ .هقذاس پبسسضذُ تَسظ ایي پبسسش ّویطِ یک لیست خبلی است .یؼٌی ایي پبسسش ّویطِ ) ([], lstببصهیگشداًذ کِ دس آى lst لیست تَکيّبیی است کِ بِ ایي پبسسش دادُ ضذُاست. دٍم optional prاست کِ ایي پبسسش ًیض ّویطِ هَفق هیضَد .ایي پبسسش دس ٍاقغ ّوبى pr <|> emptyseqاست کِ ابتذا prسا اهتحبى هیکٌذ ٍ دس غَست ضکستخَسدى آى ّیچ تَکٌی هػشف ًویکٌذ (یؼٌی emptyseqسا اجشا هیکٌذ) .اهب اص آىجبیی کِ خشٍجی emptyseqاص ًَع ] [aاست ببیذ خشٍجی ً prیض تغییش دادُ ضذُ (یؼٌی modifyضَد) ٍ بِ غَست لیست دسبیبیذ تب بتَاى اص تشکیبگش >|< استفبدُ کشد .بِ ایي تشتیب هقذاس پبسسضذُ تَسظ optional prدس غَست هَفق بَدى prیک لیست بب یک ػضَ است (کِ ایي ػضَ ّوبى هقذاس پبسسضذُ تَسظ prاست) ٍ دس غَست ضکستخَسدى prیک لیست خبلی خَاّذ بَد .دس ًتیجِ تببغ optionalاص ًَع صیش خَاّذ بَد: ]Parser a -> Parser [a پبسسشّبی اٍلیِ تٌْب پبسسشّبی اٍلیِای کِ بشای ایي صببى الصم داسین سِ پبسسش صیش است: :: Parser Val number :: Parser Variable variable :: String -> Parser String literal البتِ تببغ literalدس حقیقت یک تشکیبگش است اهب چَى بِ ًحَُی تؼشیف دادُی Tokenهشبَط است دس ایي قسوت قشاس دادُضذُ ٍ بب تشکیبگشّبی دیگش کِ تب حذ خَبی ًسبت بِ تؼشیف ایي دادُّب هستقل ّستٌذ هؼشفی ًطذُاست. بب تَجِ بِ تَضیحبت دادُضذُ بشای Parser aدقت کٌیذ کِ numberببیذ تببؼی ببضذ کِ لیستی اص تَکيّب سا هیگیشد ٍ سؼی هیکٌذ یک ػذد بخَاًذ .دس غَست ضکستخَسدى ببیذ Nothingببصگشداًذُ ٍ دس غَست هَفقضذى ببیذ ػذد خَاًذُضذُ بِ اضبفِی ببقیهبًذُی تَکيّب سا ببصگشداًذ .یؼٌی تؼشیف ایي پبسسش بِ سبدگی بِ غَست صیش است. )number (Number n : s) = Just (n,s = Nothing تمریه وهم: _ number دٍ پبسسش اٍلیِی literal ٍ variableسا بشای هتغیشّب ٍ سضتِّبیی کِ بِ غَست لفظی دس صببى ٍجَد داسًذ پیبدُسبصی کٌیذ .دقت کٌیذ کِ literal strیک پبسسش است کِ دقیقب بِ دًببل سضتِی ٍسٍدیاش (یؼٌی )strدس هتي بشًبهِ خَاّذ گطت ٍ بٌب بش ایي ببیذ تَکيّبی اص ًَع Symbolسا استفبدُ کٌذ. ًَضتي پبسسش بشای دستَسّب ٍ ػببستّب اکٌَى هیتَاًین بب کٌبس ّن قشاس دادى پبسسشّبی اٍلیِ ٍ تشکیبگشّب پبسسشّبی پیچیذُتش سا پیبدُسبصی کٌین .بِ ضببّت بیي پیبدُسبصی ایي پبسسشّب ٍ تؼشیف گشاهش صببى بشًبهًَِیسی دقت کٌیذ .دس ٍاقغ ،بِ جبی ّش سضتِی تشهیٌبل دس گشاهش ببیذ پبسسش هشبَط کِ بب استفبدُ اص literalسبختِ هیضَد سا قشاس دّین ٍ بشای ّش هتغیش ببیذ پبسسش هشبَط بِ آى هتغیش سا قشاس دّین .بشای سبختي قسوتّبیی کِ پطت سش ّن قشاس گشفتِاًذ اص تشکیبگش >&< استفبدُ کشدُ ٍ بشای سبختي قسوتّبیی کِ بب | سبختِ ضذُاًذ اص تشکیبگش >|< استفبدُ هیکٌین. ّنچٌیي قسوتّبیی کِ دس بشاکت قشاس گشفتِاًذ سا هیتَاًین بب استفبدُ اص optionalپیبدُسبصی کٌین .بشای تغییش هقذاس پبسسضذُ تَسظ پبسسشّبیی کِ بب optionalسبختِ ضذُاًذ اص تَابؼی بب ًبم … optاستفبدُ هیکٌین کِ بب استفبدُ اص تشکیبگش modifyهقبدیش سا بِ فشهی کِ ًیبص داسین دس خَاٌّذ آٍسد .بشای هثبل پبسسش بشای ػببستّب بِ غَست صیش تؼشیف خَاّذ ضذ: exp = (aexp <&> optional (literal “>” <&> aexp)) `modify` optGreater = e1 )][ optGreater (e1, = Greater e1 e2 )])optGreater (e1, [(gt, e2 ”= error “impossible _ optGreater بِ ّویي تشتیب پبسسش بشای دستَسّبی ایي صببى بِ غَست صیش خَاّذ بَد: command = (unitcom <&> optional (literal “;” <&> command)) `modify` optSeq )unitcom = whilecom <|> (ifcom <|> assign تمریه = c1 )][ optSeq (c1, = Seq c1 c2 )])optSeq (c1, [(semicol, c2 ”= error “impossible _ optSeq دهم :بب تَجِ بِ قَاًیي گشاهشی دادُضذُ بشای صببى بشًبهًَِیسی ٍ هثبلّبی ببال پبسسشّبی هشبَط بِ cexp ٍ bexp ،aexpسا بٌَیسیذ .بشای ایيکبس بِ تَابغ ً unparenth ٍ optMult ٍ optSubیبص خَاّیذ داضت .تَابغ optMult ٍ optSubهطببِ تَابغ optGreaterخَاٌّذ بَد ٍ تببغ unparenthببیذ تٌْب پشاًتضّب سا اص هقذاس پبسسضذُ تَسظ cexpحزف کٌذ. تمریه یازدهم: پبسسشّبی هشبَط بِ assign ٍ ifcom ،whilecomسا بٌَیسیذ .بشای ایي کبس بِ تَابغ ٍ mkWhileNode ً mkAssignNode ٍ mkIfNodeیبص خَاّیذ داضت. دقت کٌیذ کِ بشای سبدگی کبس پبسسشّب سا بذٍى تَاًبیی دقیقی بشای هطخعکشدى خغبّب سبختِاین .بب ٍجَد ایي دقت کٌیذ کِ هی ضذ تشکیبگشّب سا بِ سبدگی بِ گًَِای تغییش داد کِ بِ دسستی خغبّب سا اص پبسسشّبی کَچکتش گشفتِ ٍ خغبی ًْبیی سا هطخع کٌٌذ .بب ایي ٍجَد ًیبص بِ تببؼی داسین کِ ًتیجِی ًْبیی ػولیبت سا گشفتِ ٍ هطخع کٌذ کِ آیب ًتیجِ هَفق بَدُ است یب خیش ٍ دس غَست هَفق بَدى ًتیجِ ًْ ASTبیی کِ ّوبى هقذاس پبسسضذُ تَسظ پبسسش ًْبیی است سا ببصگشداًذ .دقت کٌیذ کِ ضکست خَسدى ًتیجِ هیتَاًذ بِ دلیل ضکست خَسدى کل پبسسش ببضذ یب بِ دلیل ٍجَد تَکيّبیی کِ تَسظ پبسسش استفبدُ ًطذُاًذ( .دس غَست ٍجَد ایي تَکيّب یؼٌی قسوتی اص بشًبهِ تَسظ پبسسش کلی بشًبهِّب استفبدُ ًطذُاًذ کِ یک خغب است) .بشای ایي کبس ببیذ تببؼی اص ًَع صیش بٌَیسین: report :: Maybe (a, [Token]) -> a بشای هطخع کشدى تَکيّبی اضبفِ دس غَست اضبفِ آهذى تَکيّب ببیذ تببؼی داضتِ ببضین کِ آىّب سا بِ سضتِّبی خَاًب تبذیل کٌذ: lit :: Token -> String “ “ lit (Ident s) = s ++ “ “ lit (Symbol s) = s ++ “ “ lit (Number s) = show s ++ حبل هیتَاًین تببغ reportسا تؼشیف کٌین. ”= error “Parse Error report Nothing = c ))][report (Just (c, = error (stringwith ))report (Just (c,xs (“Syntax error \n Unparsed:-\n”, ))“ “, “\n”) (map lit xs = stringwith (front, sep, back) ls let sepback [] = back sepback [a] = a ++ back sepback (a:xs) = a ++ sep ++ sepback xs in front ++ sepback ls بِ ایي تشتیب هیتَاًین تببؼی کِ لیست تَکيّب سا گشفتِ ٍ یک Commandتحَیل هیدّذ سا پیبدُسبصی کٌین( .دقت کٌیذ کِ کل بشًبهِ دس ٍاقغ یک Commandاست). mainParser :: [Token] -> Command mainParser = report . command دس ایي لحظِ بْتش است حتوب تَابغ ًَضتِ ضذُی خَد سا بش سٍی ٍسٍدیّبی هختلف کِ ببیذ لیستی اص تَکيّب کِ بِ غَست دستی سبختِضذُ ببضٌذ اجشا کٌیذ ٍ اص دسستی ػولکشد آىّب هغوئي ضَیذ. ًَضتي lexical analyzer بشای ًَضتي lexical analyzerاص هبضیي حبلت هتٌبّی صیش استفبدُ هیکٌین. بب تَجِ بِ ایي هبضیي ،دس غَست سسیذى بِ کبساکتشّبی layoutهبًٌذ فبغلِ دس ّوبى حبلت اٍلیِ هیهبًین .دس غَست خَاًذى کبساکتشّبی پشاًتض ًیض دس ّوبى حبلت اٍلیِ هیهبًین بب ایي تفبٍت کِ بشای پشاًتضّب تَکي هٌبسب سا ایجبد هیکٌین .دس غَستی کِ یک حشف ببیٌین بِ حبلت getwordسفتِ ٍ تب صهبًی کِ حشف یب ػذد یب underlineببیٌین دس آى حبلت هیهبًین .ایي حبلت هطخعکٌٌذُی تَکيّبی اص ًَع identifierاست .البتِ دقت کٌیذ کِ تؼذادی اص ّsymbolب ًیض دس ایي حبلت قشاس هیگیشًذ کِ ببیذ بؼذا جذا ضًَذّ .نچٌیي حبلتّبی getsymbol ٍ getnumبشای خَاًذى ػذدّب ٍ ّsymbolبی ًطبًِای (هثال ”= “:یب ”>“) ّستٌذ. بشای جذاسبصی ّsymbolبی حشفی (هبًٌذ ” )“Whileاص ّ identifierب اص یک تببغ استفبدُ هیکٌین کِ یک سضتِ گشفتِ ٍ keyword بَدى یب ًبَدى آى سا هطخع هیکٌذ. keyword :: String -> Bool ّنچٌیي تببغ دیگشی هیًَیسین کِ بب استفبدُ اص خشٍجی keywordبشای هب تَکي هتٌبظش بب یک سضتِ سا بِ دسستی بسبصد .یؼٌی اگش identifierبَد یک تَکي اص ًَع ٍ identifierاگش keywordبَد یک تَکي اص ًَع symbolبسبصد. keycheck :: String -> Token تمریه ديازدٌ :تببغّبی keycheck ٍ keywordسا پیبدُسبصی کٌیذ. بشای تطخیع کبساکتشّبی خَاًذُضذُ بِ چٌذیي تببغ بشای هطخع کشدى ًَع کبساکتشّب ًیبص داسین. تمریه سیسدٌ :تببغ isLetterسا پیبدُسبصی کٌیذ .ایي تببغ ببیذ هطخع کٌذ کِ کبساکتش ٍسٍدیاش یک حشف کَچک یب بضسگ است یب خیش. تمریه چهاردٌ: تببغ letDigEtcسا پیبدُسبصی کٌیذ .ایي تببغ ببیذ هطخع کٌذ کبساکتش ٍسٍدیاش یک حشف ،ػذد یب underline است یب خیش .تببغ layoutسا پیبدُسبصی کٌیذ کِ هطخع هیکٌذ کبساکتش ٍسٍدیاش یک کبساکتش اص ًَع فبغلِ است یب خیش .تببغ symbolcharسا پیبدُسبصی کٌیذ کِ هطخع هیکٌذ کبساکتش ٍسٍدیاش یکی اص ًطبًِّبی * ; ٍ = ،: ،> ،- ،است یب خیش .تببغ intOfDigitسا پیبدُسبصی کٌیذ کِ هقذاس ػذدی کبساکتش ٍسٍدی سا هطخع کٌیذ( .هثال بشای ٍسٍدی ’ ‘5ػذد 5سا ببصگشداًذ ).ایي تببغ اص ًَع Char -> Intخَاّذ بَد. بشای ًَضتي lexical analyzerاص تببغ ّبی صیش استفبدُ خَاّین کشد. ]:: String -> String -> [Token getword ]:: String -> String -> [Token getsymbol ]:: Int -> String -> [Token getnum ایي تَابغ بِ غَست هطخع بِ حبلتّبی هختلف هبضیي حبلت هتٌبّی دادُضذُ هشبَط ّستٌذٍ .سٍدی اٍل ایي تَابغ بشای جوغآٍسی کبساکتشّبی دیذُضذُی کًٌَی است .بشای هثبل دس getwordتب صهبًی کِ کبساکتشّبیی اص ًَع letDigEtcببیٌین آىّب سا بب فشاخَاًی ببصگطتی دس ٍسٍدی اٍل تببغ پطت سش ّن جوغآٍسی هیکٌین ٍ دس ًْبیت بب سسیذى بِ یک کبساکتش otherیؼٌی صهبًی کِ wordهَسد ًظش توبم ضذُاست بب استفبدُ اص تببغ keycheckکِ قبال تؼشیف ضذُبَد تَکي هَسد ًظش سا هیسبصین .بِ ّویي تشتیب تَابغ getnum ٍ getsymbolکبساکتشّبی اص ًَع digit ٍ symbolسا جوغآٍسی کشدُ ٍ دس ًْبیت بِ تَکي تبذیل هیکٌٌذ .حبل هیتَاًین تببغ ًْبیی سا بٌَیسین. ]lex :: String -> [Token ][ = ][ lex lex (a:x) = if layout a then lex x else if a == ‘(‘ then Symbol “(“ : (lex x) else if a == ‘)’ then Symbol “)” : (lex x) else if isLetter a then getword [a] x else if isDigit a then __________ else if symbolchar a then ________ else ))error (“Lexical error: unrecognized token “ ++ (a:x ])= [keycheck (reverse l ][ getword l = if letDigEtc a )getword l (a:x then getword (a:l) x ))else (keycheck (reverse l)) : (lex (a:x تمریه پاوسدهم: پیبدُسبصی تببغ lexسا توبم کٌیذّ .نچٌیي تَابغ getnum ٍ getsymbolسا پیبدُسبصی کٌیذ .بِ یبد داضتِ ببضیذ کِ تببغ getnumببیذ یک ػذد سا جوغآٍسی کٌذ (بب استفبدُ اص تببغ ًِ ٍ )intOfDigitیک سضتِ سا. بِ ایي تشتیب هفسش کبهل هیضَد ٍ هیتَاًیذ آى سا بش سٍی بشًبهِّبیی کِ کبهال بِ غَست سضتِ ًَضتِ ضذُاًذ اجشا ٍ تست کٌیذ.
© Copyright 2026 Paperzz