Pegjs: كيفية الحفاظ على فواصل المسافات؟

تم إنشاؤها على ٣ أكتوبر ٢٠١٩  ·  6تعليقات  ·  مصدر: pegjs/pegjs

نوع القضية

  • تقرير الشوائب: _ no_
  • طلب الميزة: _ no_
  • السؤال: _نعم_
  • ليست مشكلة: _لا _

المتطلبات الأساسية

  • هل يمكنك إعادة إظهار المشكلة ؟: _نعم_
  • هل بحثت في مشكلات المستودع ؟: _نعم_
  • هل قمت بفحص المنتديات ؟: _نعم_
  • هل أجريت بحثًا على الويب (google ، yahoo ، إلخ) ؟: _نعم_

أجد صعوبة في جعل محلل PEG.js يحتفظ بالمسافات البيضاء الأصلية للمعادلة.

السلوك الحالي: 2 * 5 + SUM(1, 2, 3)

[
   "2",
   "*",
   "5",
   "+",
   "SUM",
   "(",
   [
      "1",
      ",",
      "2",
      ",",
      "3"
   ],
   ")"
]

السلوك المطلوب : 2 * 5 + SUM(1, 2, 3)

[
   "2",
   " ",
   "*",
   " ",
   "5",
   " ",
   "+",
   " ",
   "SUM",
   "(",
   [
      "1",
      ",",
      " ",
      "2",
      ",",
      " ",
      "3"
   ],
   ")"
]

القواعد المراد نسخها: https://pastebin.com/zpwqT6Uw
ملعب PEG.js https://pegjs.org/online

ماذا ينقصني؟

التعليق الأكثر فائدة

@ marek-baranowski بينغ لطيف آخر: smiley_cat:

أيضًا ، قمت بكتابة PEG.js plugin pegjs-syntactic-Actions لتسهيل تصحيح الأخطاء النحوية ، وتحديد الأحرف التي يتم التقاطها بواسطة أي قاعدة بشكل مستقل عن الإجراءات ، والتي ربما تكون مشكلتك هنا كما هو موضح بواسطة StoneCypher.

المنطق وراء هذا البرنامج المساعد هو: أجد أنه من الصعب في كثير من الأحيان / أحيانًا فهم النتيجة العالمية عندما لا يكون ما نتوقعه ، لأنه ناتج عن مزيج من العديد من الإجراءات الصغيرة ، وإيجاد الإجراء الذي يتصرف بشكل سيء / بشكل صارم يمكن أن يكون استهلاك الوقت. باستخدام هذا المكون الإضافي ، نرى القاعدة التي تلتقط الحرف ، وتعطي اسم الإجراء الذي سيتم العمل عليه.

ال 6 كومينتر

futagoza آسف للغاية لإزعاجك ، لكنها المرة الأولى التي أتعامل فيها مع PEG.js وهذه المشكلة بالغة الأهمية بالنسبة لي. هل لي أن أسألك عن القليل من التلميح؟

أنا في حاجة إليها،
ماريك

حاولت البحث في القواعد النحوية (بالأمس والآن فقط) ولكن نظرًا لأنه من الصعب حقًا فهمها (بغض النظر عن اصطلاحات التسمية ، فإن التنسيق ، لأكون صادقًا ، منتشر في كل مكان) ، استغرق الأمر بعض الوقت لتعقب الحل:

  1. القواعد التي تستهلك مساحة والبيانات تعيدها (على سبيل المثال ، const تُرجع [left_space, cnst, right_space] )
  2. أي قاعدة / إجراء يأخذ النتيجة يجب أن يفعل شيئًا كالتالي: [].concat.apply([], con)

حتى مع ذلك ، لأكون صادقًا معك ، يبدو هذا كحل مبتكر بالنسبة لي. هل لديك رابط لمواصفات أو شيء من هذا القبيل؟ من المفيد معرفة القواعد التي يمكنني تغييرها ولا يمكنني تغييرها للحصول على النتيجة المرجوة بدون حل الاختراق أعلاه.

إذا لم يكن الأمر كذلك ، طالما أنك على استعداد لتخصيص الوقت وترتيب القواعد النحوية وإعادة تسمية بعض القواعد (لذلك من الأسهل معرفة ما تريد) ، فسأحاول بكل سرور أن أقوم بطعنة أخرى 😉

@ marek-baranowski - آسف لم أر هذا حتى الآن. نأمل أن يكون هذا لا يزال مفيدًا لك

إذا كنت تريد الاحتفاظ بالمسافات ، فما عليك سوى معاملتها كمحتوى قابل للمطابقة.

ليس من الواضح حقًا ما تريده لمساحتين. يمكن أن يكون لديك إما سلسلة من مسافتين ، أو مصفوفة من سلسلتين بمسافة واحدة. في العادة كنت أتوقع الأول ، لكن ... كل ما تبذلونه من الأشياء هو لكل شخصية

أيضًا ... لماذا تريد أحرفًا ضالة كهذه ، باستثناء استدعاء الوظيفة؟ يجب أن يقوم المحلل اللغوي بتلخيص هذه الأمور لك.

على أي حال

هذا ما طلبته:

Document = Expression*

Whitespace
  = tx:[ \r\n]+ { return tx.join(''); }

Number
  = str:[0-9]+ { return str.join(''); }

Oper
  = '+'
  / '-'
  / '/'
  / '*'
  / ','

Label
  = l:[a-zA-Z]+ { return l.join(''); }

Parens 
  = '(' Whitespace? ex:Expression* Whitespace? ')' { return ex; }

Expression 
  = Number 
  / Oper
  / Whitespace
  / Label
  / Parens
  / [^()]+

image

الشيء هو أنني لست مقتنعًا تمامًا أن هذا ما تريده بالفعل. على سبيل المثال ، يمكنك بدلاً من ذلك تحليل الأرقام والعوامل ، وإرجاع شكل عقدة معياري لكل منها:

Document = Expression*

Whitespace
  = tx:[ \r\n]+ { return { 
    ast: 'whitespace', value: tx.join('') 
  }; }

Number
  = str:[0-9]+ { return {
    ast: 'number', value: parseInt(str,10)
  }; }

Oper
  = '+' { return { ast: 'oper', value: 'add' }}
  / '-' { return { ast: 'oper', value: 'subtract' }}
  / '/' { return { ast: 'oper', value: 'divide' }}
  / '*' { return { ast: 'oper', value: 'multiply' }}
  / ',' { return { ast: 'oper', value: 'sequence' }}

Label
  = l:[a-zA-Z]+ { return { 
    ast: 'label', value: l.join('') 
  }; }

Parens 
  = '(' Whitespace? ex:Expression* Whitespace? ')' { 
    return { ast: 'parens', value: ex 
  }; }

Expression 
  = Number 
  / Oper
  / Whitespace
  / Label
  / Parens
  / [^()]+

الآن لا تزال لديك مساحتك البيضاء ، ولكن لديك أيضًا شجرة تحليل مناسبة ، ولا تحتاج إلى كتابة محلل لتحليل ناتج المحلل اللغوي الخاص بك ، كما أنه من السهل الآن بدء إضافة ميزات منتظمة مثل أرقام الأسطر وما إلى ذلك.

image

@ marek-baranowski - أرغب في تقليل حجم أداة تعقب المشكلات هذه إلى حد ما

إذا كان ما سبق هو ما تحتاجه ، هل تفضل بإغلاق هذه المشكلة؟ شكرا 😄

إذا لم يكن الأمر كذلك ، فيرجى إخبارنا بالسبب وسأحاول مرة أخرى

@ marek-baranowski بينغ لطيف آخر: smiley_cat:

أيضًا ، قمت بكتابة PEG.js plugin pegjs-syntactic-Actions لتسهيل تصحيح الأخطاء النحوية ، وتحديد الأحرف التي يتم التقاطها بواسطة أي قاعدة بشكل مستقل عن الإجراءات ، والتي ربما تكون مشكلتك هنا كما هو موضح بواسطة StoneCypher.

المنطق وراء هذا البرنامج المساعد هو: أجد أنه من الصعب في كثير من الأحيان / أحيانًا فهم النتيجة العالمية عندما لا يكون ما نتوقعه ، لأنه ناتج عن مزيج من العديد من الإجراءات الصغيرة ، وإيجاد الإجراء الذي يتصرف بشكل سيء / بشكل صارم يمكن أن يكون استهلاك الوقت. باستخدام هذا المكون الإضافي ، نرى القاعدة التي تلتقط الحرف ، وتعطي اسم الإجراء الذي سيتم العمل عليه.

أوه ، هذا رائع حقًا في الواقع

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات

القضايا ذات الصلة

richb-hanover picture richb-hanover  ·  7تعليقات

StoneCypher picture StoneCypher  ·  8تعليقات

dmajda picture dmajda  ·  7تعليقات

futagoza picture futagoza  ·  13تعليقات

emmenko picture emmenko  ·  15تعليقات