سكالا موزعي combinator - التمييز بين سلاسل عدد وسلاسل متغيرة
-
05-07-2019 - |
سؤال
وأنا التمارين محلل combinator كاي هورستمان، وأنا أتساءل عن أفضل طريقة للتمييز بين السلاسل التي تمثل الأرقام والسلاسل التي تمثل متغيرات في بيان المباراة:
def factor: Parser[ExprTree] = (wholeNumber | "(" ~ expr ~ ")" | ident) ^^ {
case a: wholeNumber => Number(a.toInt)
case a: String => Variable(a)
}
والسطر الثاني هناك، "الحالة: wholeNumber" غير قانوني. فكرت في التعبير العادي، ولكن لا يمكن العثور على طريقة للحصول عليه للعمل مع "القضية".
المحلول
وأود أن تقسيم عنه قليلا، ودفع تحليل حالة في |
. هذه هي واحدة من مزايا combinators وحقا LL (*) التوزيع بشكل عام:
def factor: Parser[ExprTree] = ( wholeNumber ^^ { Number(_.toInt) }
| "(" ~> expr <~ ")"
| ident ^^ { Variable(_) } )
وأعتذر إذا كنت لم تكن مألوفة مع بناء الجملة تسطير. أساسا هذا يعني فقط "استبدال <م> ن م> المعلمة عشر إلى قيمة الدالة تتضمن". وهكذا { Variable(_) }
ما يعادل { x => Variable(x) }
.
وقليلا آخر من السحر جملة هنا هو ~>
و<~
المشغلين في مكان ~
. وتعني هذه الشركات التي إعراب هذا المصطلح ينبغي أن تشمل <م> تركيب م> من كل من أقواس، ولكن النتيجة ينبغي أن تحدد فقط من قبل نتيجة لexpr
. وهكذا، فإن "(" ~> expr <~ ")"
يطابق تماما نفس الشيء "(" ~ expr ~ ")"
، ولكنه لا يتطلب تحليل حالة اضافية لاسترداد قيمة نتيجة الداخلية من expr
.