EOS এ রাকু ব্যাকরণ বন্ধ করা (স্ট্রিংয়ের শেষ)


9

রাকু ডিএসএল-দক্ষতা শিখার অজুহাত হিসাবে একটি গানের ভাষার অনুবাদককে অন্য একটি (এবিসি থেকে অলডা) রচনার প্রক্রিয়ায়, আমি লক্ষ্য করেছি যে একটিকে সমাপ্ত করার উপায় নেই বলে মনে হয় .parse! এখানে আমার সংক্ষিপ্ত ডেমো কোডটি রয়েছে:

#!/home/hsmyers/rakudo741/bin/perl6
use v6d;

# use Grammar::Debugger;
use Grammar::Tracer;

my $test-n01 = q:to/EOS/;
a b c d e f g
A B C D E F G
EOS

grammar test {
  token TOP { <score>+ }
  token score {
      <.ws>?
      [
          | <uc>
          | <lc>
      ]+
      <.ws>?
  }
  token uc { <[A..G]> }
  token lc { <[a..g]> }
}

test.parse($test-n01).say;

এবং এটি ব্যাকরণ :: ট্রেসার প্রদর্শনের শেষ অংশ যা আমার সমস্যা দেখায়।

|  score
|  |  uc
|  |  * MATCH "G"
|  * MATCH "G\n"
|  score
|  * FAIL
* MATCH "a b c d e f g\nA B C D E F G\n"
「a b c d e f g
A B C D E F G
」

দ্বিতীয় থেকে শেষ লাইনে, FAIL শব্দটি আমাকে বলে যে পার্স রানটি ছাড়ার কোনও উপায় নেই। আমি ভাবছি এটা সঠিক কিনা? .সেস সবকিছু যেমনটি হওয়া উচিত তেমন প্রদর্শন করে, তাই ব্যর্থতাটি কতটা বাস্তব তা সম্পর্কে আমি পরিষ্কার নই? প্রশ্নটি রয়ে গেছে, "আমি কীভাবে সঠিকভাবে এমন একটি ব্যাকরণ লিখব যা কোনও ত্রুটি ছাড়াই একাধিক রেখাকে পার্স করে?"


আমি আপনার শেখার প্রক্রিয়ায় হস্তক্ষেপ করতে চাই না, তবে আপনি যদি সচেতন না হন তবে একটি এবিসি মডিউল রয়েছে
রায়ফ

1
ভাল, কমপক্ষে আমরা পরীক্ষা করার জন্য একই সুরগুলি বেছে নিই নি!
hsmyers

উত্তর:


10

আপনি যখন ব্যাকরণ ডিবাগারটি ব্যবহার করেন, এটি আপনাকে ইঞ্জিনটি কীভাবে স্ট্রিংটিকে পার্স করছে তা ঠিক দেখতে দেয় - ব্যর্থতা স্বাভাবিক এবং প্রত্যাশিত। বিবেচনা করুন, উদাহরণস্বরূপ, মিলে a+b*স্ট্রিং সঙ্গে aab। আপনার 'এ' এর জন্য দুটি ম্যাচ পাওয়া উচিত, তার পরে একটি ব্যর্থ (কারণ bতা নয় a) তবে এটি আবার চেষ্টা করে bসফলতার সাথে মিলবে match

আপনি যদি কোনও বিকল্প পরিবর্তন করেন ||(যা আদেশ প্রয়োগ করে) তবে এটি আরও সহজেই দেখা যাবে । যদি তোমার থাকে

token TOP   { I have a <fruit> }
token fruit { apple || orange || kiwi }

এবং আপনি "আমার কাছে একটি কিউই" বাক্যটি বিশ্লেষণ করুন, আপনি এটি প্রথম ম্যাচটি দেখতে পাবে "আমার একটি আছে", তারপরে "আপেল" এবং "কমলা" দিয়ে দুটি ব্যর্থ হবে এবং শেষ পর্যন্ত "কিউই" এর সাথে একটি ম্যাচ হবে।

এখন আসুন আপনার কেসটি দেখুন:

TOP                  # Trying to match top (need >1 match of score)
|  score             #   Trying to match score (need >1 match of lc/uc)
|  |  lc             #     Trying to match lc
|  |  * MATCH "a"    #     lc had a successful match! ("a")
|  * MATCH "a "      #   and as a result so did score! ("a ")
|  score             #   Trying to match score again (because <score>+)
|  |  lc             #     Trying to match lc 
|  |  * MATCH "b"    #     lc had a successful match! ("b")
|  * MATCH "b "      #   and as a result so did score! ("b ")
……………                #     …so forth and so on until…
|  score             #   Trying to match score again (because <score>+)
|  |  uc             #     Trying to match uc
|  |  * MATCH "G"    #     uc had a successful match! ("G")
|  * MATCH "G\n"     #   and as a result, so did score! ("G\n")
|  score             #   Trying to match *score* again (because <score>+)
|  * FAIL            #   failed to match score, because no lc/uc.
|
|  # <--------------   At this point, the question is, did TOP match?
|  #                     Remember, TOP is <score>+, so we match TOP if there 
|  #                     was at least one <score> token that matched, there was so...
|
* MATCH "a b c d e f g\nA B C D E F G\n" # this is the TOP match

এখানে ব্যর্থতা সাধারণ: এক পর্যায়ে আমরা <score>টোকেনের বাইরে চলে যাব , সুতরাং একটি ব্যর্থতা অনিবার্য। যখন এটি ঘটে, ব্যাকরণ ইঞ্জিনটি <score>+আপনার ব্যাকরণের পরে যা কিছু আসে তার দিকে যেতে পারে । যেহেতু কিছুই নেই, এটি ব্যর্থতার ফলে পুরো স্ট্রিংয়ের TOPমিল হয় (কারণ অন্তর্নিহিতগুলির সাথে মিল রয়েছে /^…$/)।

এছাড়াও, আপনি নিজের ব্যাকরণটি এমন নিয়ম দিয়ে পুনরায় লেখার বিষয়ে বিবেচনা করতে পারেন যা <.ws> * স্বয়ংক্রিয়ভাবে সন্নিবেশ করায় (যদি না এটি কেবলমাত্র একক স্থান হিসাবে গুরুত্বপূর্ণ):

grammar test {
  rule TOP { <score>+ }
  token score {
      [
          | <uc>
          | <lc>
      ]+
  }
  token uc { <[A..G]> }
  token lc { <[a..g]> }
}

আরও, আইএমই, আপনি ইউসি / এলসি-র জন্য একটি প্রোটোক টোকেন যুক্ত করতেও চাইতে পারেন, কারণ আপনার যখন [ <foo> | <bar> ]সর্বদা থাকে তখন তাদের মধ্যে একটি অপরিবর্তিত থাকবে যা তাদের ক্রিয়াকলাপে প্রক্রিয়াকরণকে কিছুটা বিরক্তিকর করে তুলতে পারে। আপনি চেষ্টা করতে পারেন:

grammar test {
  rule  TOP   { <score>  + }
  token score { <letter> + }

  proto token letter    {     *    }
        token letter:uc { <[A..G]> }
        token letter:lc { <[a..g]> }
}

$<letter> সর্বদা এইভাবে সংজ্ঞায়িত করা হবে।


এটি ম্যাচের অবজেক্টটি 'ব্যর্থ' এমনকি সত্য হিসাবে আউট হওয়ার বিষয়টি ব্যাখ্যা করে। আমি যে ক্ষেত্রে হতে পারে; আমি বাস্তব প্রকল্পের জন্য প্রয়োজনীয় টোকেন যুক্ত করতে ফিরে যাব;)
hsmyers

আসল ব্যাকরণ << ডাব্লু> * স্বয়ংক্রিয়ভাবে সন্নিবেশ করা পছন্দ করছে না; সম্ভবত <স্কোর> এর বাইরে জড়িত অতিরিক্ত স্তরগুলির কারণে। প্রোটো ব্যবহারের আপনার পরামর্শটি আমি কৌশলটির চারপাশে আমার মাথাটি
গুটিয়ে


আমি এমন কোড থাকা ঘৃণা করি যা আমার দরকার নেই - ডিবাগ করার জন্য আরও বেশি, এবং তারপরে এটির সমস্ত নান্দনিকতা রয়েছে! আসল সমস্যাটি হ'ল এবিসি স্পেস সম্পর্কে কোনও জবাব দেয় না। কিছু ব্যতিক্রম আছে, তবে এবং বড় আকারে, এগুলি প্রায় যেকোন জায়গায় হতে পারে। 'ব্যবহার' কেস বড় অঙ্কের স্ট্রিংগুলিতে কমাগুলির মতো কিছুটা সুগম্যতার বিষয়। সমস্যাটি বুঝতে না পারলে এবং এটিকে সর্বনিম্নে নামিয়ে না দেওয়া পর্যন্ত আমি প্রয়োজন অনুযায়ী সমস্যাটি আবার ঘুরে দেখব।
hsmyers

1
এইচএসএমআরস: কৃতজ্ঞতা জানার protoপক্ষে বোঝা খুব বেশি কঠিন নয় এবং একবার আপনি এটির ঝুলি পেয়ে গেলে তা আপনার জীবনকে আরও সহজ করে তোলে।
user0721090601
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.