Pegjs: الاختزال للأفعال الدلالية

تم إنشاؤها على ١٠ سبتمبر ٢٠١٨  ·  13تعليقات  ·  مصدر: pegjs/pegjs

سيكون من الجيد إضافة اختصار للأفعال الدلالية.

لنقل ، بدلاً من كتابة { return value } ، نكتب ، على سبيل المثال { extract } الذي تم تعريفه في المُهيئ.

على سبيل المثال:

{
  function extract(value) {
    return value;
  }
  function concat(head, tail) {
    return head ? [head].concat(tail) : [];
  }
  function toAddExpr(head, tail) {
    return { type: 'addExpr', expressions: concat(head, tail) };
  }
}

List
  = '(' _ head:Item? tail:( _ ',' _ value:Item { extract } )* _ ')' { concat }

// Another kind of list
Add
  = '(' _ head:Multiply? tail:( _ '+' _ value:Multiply { extract } )* _ ')' { toAddExpr }

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

أعتقد أنه سيكون أيضًا أكثر فائدة عندما يكون التعبير الموجود في اختصار الإجراء هو تعبير العضو { foo.bar.baz } بدلاً من مجرد المعرف { foo } . حتى يتمكن كتاب القواعد النحوية من تنظيم وظائفهم داخل كائن أو حتى وحدة نمطية.

discussion feature

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

في الواقع ، كنت أفكر ، قد تنجح هذه التغييرات:

CodeBlock "code block"
  = "=>" _ expession:CallExpression {
       return `return ${ expession };`;
     }
  / "{" <strong i="6">@Code</strong> "}"
  / "{" { error("Unbalanced brace."); }

// Will be based on ECMAScript's CallExpression
CallExpression
  = ...
  / MemberExpression

// Will be based on ECMAScript's MemberExpression
MemberExpression
  = ...
  / ValidIdentifier

// Change `LabelIdentifier` into `ValidIdentifier`

ستظل هذه الطريقة تتطلب دمج بعض الأشياء مثل التعبيرات الأساسية لـ ECMAScript (أرقام ، منطقية ، مصفوفات ، إلخ) لاستخدامها كوسيطات ، لذلك ستحتاج إلى معرفة ما يجب إضافته بعناية.


موازنة الأقواس والأقواس

لن يتم إصلاح ذلك حتى يتم تضمين محلل جافا سكريبت مناسب في المحلل اللغوي PEG.js ، ولكن لأكون صادقًا ، فأنا متردد قليلاً بشأن هذا الأمر نظرًا لوجود عدد قليل من مشاريع المكونات الإضافية التي تنشئ محللات بلغات أخرى (C ، PHP ، TypeScript ، وما إلى ذلك) ، وأنا أعمل أيضًا على لغة كمبيوتر أتمنى أن يتم إنشاء موزعات بها يومًا ما.


جنبًا إلى جنب مع _PEG.js v0.12_ ، سأعمل على OpenPEG ، والتي ستقدم حزمة NPM التي هي في الأساس نسخة مجردة من PEG.js بدون أي إنشاء JavaScript ومحلل ، ولكن هناك ميزات كافية بحيث يمكن للمشاريع القائمة على JavaScript مثل يمكن لـ PEG.js استخدامه كخلفية. عندما يخرج _v0.12_ ، سأحاول التأكد من إخطار OpenPEG بأي من مشاريع المكونات الإضافية التي تنشئ محللات مخصصة ، وقبل الإصدار 1 قم بتطبيق محلل ECMAScript 2015 الكامل في المحلل اللغوي النحوي PEG.js.

ال 13 كومينتر

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

اقترح شخص في رقم 235 بناء الجملة => لتتماشى مع وظائف الأسهم ، والتي اعتقدت أنها نظيفة وموجزة تمامًا.

  = '(' expr:some_expression ')' => expr
  ;

أميل إلى اختيار أحد الخيارات التالية لتركيب الاختصارات:

  • => expr; _ (يحتاج إلى دعم لبناء الجملة) _
  • { => expr } _ (قابل للاستخدام الآن ، لكن يحتاج إلى فك) _
  • { > expr } _ (يحتاج إلى دعم لبناء الجملة) _

لم أقرر بعد ، لذا فهو مفتوح للنقاش.

بالنسبة لما يريده OP ، سيكون من الأفضل تنفيذ مكون إضافي (بعد أو قبل تحديد بناء الجملة المختصرة) يستخدم Acorn أو @ babel / parser لفك تغليف المعرف أو تعبير العضو ، وتحويله إلى تعبير استدعاء أثناء إضافة تسميات كوسائط وإرجاع الشفرة التي تم إنشاؤها.

=> expr;

الأفضل في رأيي.

{ => expr }

يتعارض مع صيغة Javascript IMO. نظرًا لأنه داخل { } فإنك تتوقع أن تكون وظيفة سهم كاملة ( () => ).

{ > expr}

المتعامد قليلاً مع أي بناء جملة آخر في أي من PegJS أو Javascript ، لا يقرأ على الفور "هذا يعيد قيمة ، اختصار" IMO - بشكل أساسي لأنه في أقواس معقوفة ، على ما أعتقد. نفس الوسيطة مثل {=> expr} ، تتوقع أن تكون Javascript موجودة هناك.


علاوة على ذلك ، فإن إضافة بناء جملة غير JS في {} يمثل مشكلة بالنسبة لأدوات تمييز بناء الجملة ، والنظارات ، وما إلى ذلك ، أوصي بعدم استخدامها.

إذا كان بإمكاني اقتراح خيار آخر ، ربما > بحد ذاته (ليس داخل الكتلة الأصلية). يساعد ذلك في الحفاظ على محاذاة الأشياء عند تباعد القواعد عموديًا:

    = foo:bar qux:(' '+ @qix)+
    > {foo, qux}
    ;

وكذلك مضمنة

some_rule = foo:bar qux:(' '+ @qix)+ > {foo, qux};

لماذا الفاصلة المنقوطة مطلوبة من أجل '=>'؟ أرغب في إرجاع قيمة في التعليمات البرمجية المتداخلة بدلاً من استخدام buildList () على سبيل المثال:

  = "(" _ head:Expression _ tail:("," _ expr:Expression => expr)* ")" {
      return [head, ...tail]
    }

أجد هذا المنظف من استخدام الفهرس السحري (أدناه). خيار آخر هو القدرة على الإشارة إلى التسميات المتداخلة. على سبيل المثال ، ("," _ tail:Expression)* ")"

  = "(" _ head:Expression _ tail:("," _ Expression)* ")" {
      return buildList(head, tail, 2)
    }

كنت أنظر إلى parser.pegjs ، وأرى حول السطر 434 هناك CodeBlock. ما الذي يجب القيام به لتجربته؟ يقرأ رمز القاعدة ببساطة حرف المصدر ، وهو "فقط".

CodeBlock "code block"
  = "=>" __ <strong i="13">@Code</strong> // this?
  / "{" <strong i="14">@Code</strong> "}"

mikeaustin نعم ، هذا صحيح ، ولكن لا توجد طريقة لمعرفة مكان إنهاء هذا التسلسل بعد ذلك ، لذلك سوف تستهلك كل شيء بعد =>

ربما يمكن أن يكون "الكود" أكثر ذكاءً قليلاً ، حيث يوازن بين الأقواس والأقواس ، ويتعامل مع LineTerminator؟ لن يحتاج إلى معرفة JavaScript كاملة ، ولكن قد يكون ذلك أصعب مما يبدو.

في الواقع ، كنت أفكر ، قد تنجح هذه التغييرات:

CodeBlock "code block"
  = "=>" _ expession:CallExpression {
       return `return ${ expession };`;
     }
  / "{" <strong i="6">@Code</strong> "}"
  / "{" { error("Unbalanced brace."); }

// Will be based on ECMAScript's CallExpression
CallExpression
  = ...
  / MemberExpression

// Will be based on ECMAScript's MemberExpression
MemberExpression
  = ...
  / ValidIdentifier

// Change `LabelIdentifier` into `ValidIdentifier`

ستظل هذه الطريقة تتطلب دمج بعض الأشياء مثل التعبيرات الأساسية لـ ECMAScript (أرقام ، منطقية ، مصفوفات ، إلخ) لاستخدامها كوسيطات ، لذلك ستحتاج إلى معرفة ما يجب إضافته بعناية.


موازنة الأقواس والأقواس

لن يتم إصلاح ذلك حتى يتم تضمين محلل جافا سكريبت مناسب في المحلل اللغوي PEG.js ، ولكن لأكون صادقًا ، فأنا متردد قليلاً بشأن هذا الأمر نظرًا لوجود عدد قليل من مشاريع المكونات الإضافية التي تنشئ محللات بلغات أخرى (C ، PHP ، TypeScript ، وما إلى ذلك) ، وأنا أعمل أيضًا على لغة كمبيوتر أتمنى أن يتم إنشاء موزعات بها يومًا ما.


جنبًا إلى جنب مع _PEG.js v0.12_ ، سأعمل على OpenPEG ، والتي ستقدم حزمة NPM التي هي في الأساس نسخة مجردة من PEG.js بدون أي إنشاء JavaScript ومحلل ، ولكن هناك ميزات كافية بحيث يمكن للمشاريع القائمة على JavaScript مثل يمكن لـ PEG.js استخدامه كخلفية. عندما يخرج _v0.12_ ، سأحاول التأكد من إخطار OpenPEG بأي من مشاريع المكونات الإضافية التي تنشئ محللات مخصصة ، وقبل الإصدار 1 قم بتطبيق محلل ECMAScript 2015 الكامل في المحلل اللغوي النحوي PEG.js.

FWIW ، لقد بدأت في استخدام القوالب الحرفية لهذا الغرض. كما أنه يساعدني في إبراز بناء الجملة لـ JS بواسطة محرر النصوص الخاص بي ...

exports = module.exports = functionBodies`${grammarScript}
...
objectText =
    head:word
    rest:(_txt_ word)*
    ${f=>{
        return new Txt(rest.reduce((a,b)=>([...a,...b]),[head]))
        }}
word = ch:(wordCharacter/escapedCharacter)+ ${chJoin}
...
`
function functionBodies(glue, ...fns){
    return glue.map( (str,i) => str + (fns[i]||'').toString().replace(/^[^{]*/,'').replace(/[^}]*$/, '') ).join('')
    }

function chJoin(ch){return ch.join('')}

ماذا عن استخدام مشغل الأنابيب المقترح (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Pipeline_operator)؟ بما أنك ، في الأساس ، تطلب نقل البيانات؟

{
  function extract(value) {
    return value;
  }
  function concat(head, tail) {
    return head ? [head].concat(tail) : [];
  }
  function toAddExpr(head, tail) {
    return { type: 'addExpr', expressions: concat(head, tail) };
  }
}

List
  = '(' _ head:Item? tail:( _ ',' _ value:Item |> extract )* _ ')' |> concat

// Another kind of list
Add
  = '(' _ head:Multiply? tail:( _ '+' _ value:Multiply |> extract  )* _ ')' |> toAddExpr

لا ينبغي أن يحدث أي من هذا. يجب ألا يكون هناك بناء جملة قصير.

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

في حين أن هذه فكرة رائعة ، إلا أنها تخلق الكثير من الغموض النحوي مقابل JavaScript. أي شخص قام بتحليل JS وتذكر ما كانت عليه الكارثة with يعرف أن هذا سيؤدي في الأساس إلى قتل محلل.

بدلاً من محاولة إنشاء أشياء جديدة رائعة ، يجب علينا فقط دعم جافا سكريبت. وظائف الأسهم أقدم من ES6 و ES6 من عام 2015. تم حل هذا منذ ست سنوات. لا ينبغي أن يحدث أي اختراع هنا.

مشغل الأنبوب معيب بشكل سيئ وربما لن يصل في الواقع إلى جافا سكريبت ، وتتراجع كل من اللغة التي جاءت في الأصل من (F #) واللغة التي أشاعها (الإكسير). علاوة على ذلك ، هذا ليس الأنابيب بأي حال من الأحوال.

كان السبب وراء نجاح PEG هو أنه كان ضئيلًا ، وظل قريبًا من اللغة ، مما سمح له بأن يكون سريعًا وصغيرًا ويمكن التنبؤ به.

وظائف الأسهم أقدم من ES6 و ES6 من عام 2015. تم حل هذا منذ ست سنوات. لا ينبغي أن يحدث أي اختراع هنا.

أوه. هذه أخبار بالنسبة لي. هل ترغب في التوسع؟

كان السبب وراء نجاح PEG هو أنه كان ضئيلًا ، وظل قريبًا من اللغة ، مما سمح له بأن يكون سريعًا وصغيرًا ويمكن التنبؤ به.

يعود سبب نجاح PEG (كمفهوم ، وليس هذه المكتبة) إلى قدرتها على تمثيل القواعد النحوية المعقدة (العودية ، وما إلى ذلك) بطريقة مبسطة. لم يتم اختراع Packrat مع هذه المكتبة ؛ انها ليست بناء الجملة. إنها خوارزمية.

وظائف الأسهم أقدم من ES6 و ES6 من عام 2015. تم حل هذا منذ ست سنوات. لا ينبغي أن يحدث أي اختراع هنا.

أوه. هذه أخبار بالنسبة لي. هل ترغب في التوسع؟

لا أعرف حقًا ما الذي تطلبه.

وظائف الأسهم أقدم من ES6. كانت هذه ثاني أكبر معركة في ES6 ، وهو ما أدى إلى خروج ES4 عن مساره ، وما أدى إلى خروج ES5 + عن مساره. كان الجميع يسأل عنهم ، في تلك المرحلة ، منذ منتصف التسعينيات ، لأنهم في الواقع موجودون بالفعل في E4X ، وتم نقلهم بعيدًا لأن Google و Apple ألقوا نوبة في Hixie حول اختراع Microsoft لأي شيء.

أنت تعرف الآن E4X باسم React ، وتعتقد أن Facebook اخترعه. يعتقد موقع Facebook أنهم قاموا بنهب Hyperscript. من الواضح أن الرجل Hyperscript كان يعيد تنفيذ شيء مفيد من IE القديم.

كان من المقرر استبعادهم من ES6 تمامًا ، تمامًا مثل سلاسل القوالب ، ولكن بعد ذلك جاء Coffeescript وقدم لمجتمع JS كلاهما ، ثم صرخ مجتمع JS حتى تحرك أعضاء ECMA. استغرق 18 شهرًا فقط

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

الأهم بالنسبة لي ، إذا تم ذلك باستخدام وظيفة السهم ، فلن تتم إضافة أي شيء.

اختلافات Peg عن JS ضئيلة للغاية. دعم هذا عن طريق القيام بأشياء ES6 يعني أن القائمة لا تتغير.

هذا قيمة للغاية.


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

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

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

لاحظ أيضًا أن PEG لها ثلاثة سقوف خطيرة معقدة.

أولاً ، يجب أن يحتوي أي شيء تريد إدخاله في قواعد الوتد على تعبير اندماجي لا يطغى على ذاكرة التخزين المؤقت للجهاز المحلي ومعدلات التقييم (على سبيل المثال # 623)

اثنان ، العديد من الوظائف الشائعة ، مثل تحليل BNF ، غالبًا ما تكون صعبة بوحشية في الربط (في المثال رقم 489)

ثالثًا ، من الجدير بالذكر أن كل مكتبة JS PEG الأخرى ، حتى تلك الأكثر قوة بشكل ملحوظ ، قد فشلت. حاولت الابتعاد ، وعدت عدة مرات. على وجه الخصوص ، حاولت التبديل إلى canopy عدة مرات ، لأنه يسمح لي باستهداف c ، ruby ، و python بالإضافة إلى ذلك إلى javascript

من المؤكد أن كل ما يمكنني التحدث عنه هو أكثر من عشرين شخصًا أعرفهم ممن يستخدمونها. ويمكنني ، لأنني سألت قبل يومين ، عندما أدركت أن غير المشرف الجديد كان يتخلص من البرنامج ويستبدله بشيء صنعه من الصفر ، بعد سنوات من عدم نشر أي تغييرات

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

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

.

لم يتم اختراع Packrat مع هذه المكتبة ؛ انها ليست بناء الجملة. إنها خوارزمية.

لم أقل شيئًا عن باكرات ، يا صديقي. لست متأكدًا مما تحاول تصحيحه.

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

في الواقع ، تجعلك معظم كتب haskell التمهيدية تقوم بثلاثة أو أربعة موزعي حزم مختلفة ، لأنها طريقة رائعة للتعليق على مشاكل أداء نهج haskell في monads ، وهم يريدون أن يوضحوا لك كيفية تغيير أسلوب الكتابة packrats (أي تغيير الخوارزمية) تؤدي إلى نتائج أفضل.

.

يرجى إعادة النظر في ذلك رفض. هذه المكتبة ميتة منذ ثلاث سنوات ، وأود إحيائها الآن.

يرجع جزء من سبب موت المكتبة إلى أن الأشخاص يواصلون محاولة ابتكار ميزات جديدة ، بدلاً من إجراء صيانة بسيطة ، مثل إضافة وظيفة الوحدة النمطية es() التي كانت موجودة في المطورين لمدة عامين

يجب أن أقوم بتعديل موزعي PEG يدويًا عن طريق قطع الخطوط وتدبيس جافا سكريبت المكتوب يدويًا في نهايتها

يجب أن تغلق العيون المرصعة بالنجوم لفترة قصيرة ، ويجب أن تبدأ بعض الأكواع الدهنية العملية. مكتبة PEG هي مكتبة NPM الرئيسية الوحيدة التي رأيتها على الإطلاق مع تراجع الاستخدام. بالنظر إلى أنني لست على علم بوجود بديل معقول ، فهذا أمر غريب ومربك بالنسبة لي.

image

لدي إصلاحات أخطاء أريد المساهمة بها الآن ، لكن لا يمكنني ذلك ، لأن

  1. لم يُنشر 0.10 منذ رحيل ضمجدة ،
  2. 0.11 عمره ثلاث سنوات ، ولم يُنشر مطلقًا ، وأُعلن قبل شهر ولن يُنشر أبدًا ، و
  3. البديل ، 0.12 ، ليس مثبتًا على الإطلاق ، ولكنه شيء كتبه الرجل الآخر من الصفر بلغة برمجة مختلفة ، ولا يمكن لأي منا رؤيته

أعلم أن هذا أمر غير مهذب ، لكن علينا أن نواجه مقتل هذه المكتبة

حان الوقت لمواجهة أننا بحاجة إلى قبول عملية تطوير عادية إذا كانت هذه المكتبة ستشاهد التحديثات مرة أخرى. إنه عام 2020. لم نشهد أي شيء منذ عام 2017.

لا ، لا يحتسب فرع التطوير. ومعيل الجديدة ستعمل لديك لإعادة فتح مجموعة كبيرة من القضايا، لأن 0.11 ليس من نوعية كافية، والبدء من جديد من 10 هو أقل كثيرا من العمل من تحديد 11

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