Pegjs: قم بتوفير طريقة موجزة للإشارة إلى قيمة إرجاع واحدة من تسلسل

تم إنشاؤها على ٢٩ يناير ٢٠١٤  ·  21تعليقات  ·  مصدر: pegjs/pegjs

هذا شائع إلى حد ما بالنسبة لي. أرغب في إرجاع الجزء ذي الصلة فقط من التسلسل في تسمية init. في هذه الحالة ، فقط تعبير الواجب.

pattern:Pattern init:(_ "=" _ a:AssignmentExpression {return a})?

أوصي بإضافة تعبير @ الذي سيعيد التعبير التالي فقط من التسلسل. لذلك سيبدو المثال أعلاه كما يلي:

pattern:Pattern init:(_ "=" _ @AssignmentExpression)?

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

  • # 427 السماح بإرجاع نتيجة مطابقة لتعبير محدد في قاعدة بدون إجراء
  • # 545 امتدادات بسيطة في بناء الجملة لاختصار القواعد النحوية
feature

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

هل تم إصدار هذا لعلامة dev على npm بالفعل؟

https://www.npmjs.com/package/pegjs/v/0.11.0-dev.325

ال 21 كومينتر

أوافق على أن هذه مشكلة شائعة. لكني لست متأكدًا مما إذا كان الأمر يستحق الحل. بعبارة أخرى ، لست متأكدًا مما إذا كان يحدث كثيرًا بشكل كافٍ وما إذا كان يسبب ألمًا كافيًا لضمان إضافة تعقيد إلى PEG.js من خلال تنفيذ حل ، مهما كان ذلك.

سأبقي هذه المشكلة مفتوحة وأضع علامة عليها للنظر فيها بعد 1.0.0.

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

rule = space* a:(text space+ otherText)+ newLine* { return a; }

لقد حصلت:

rule = space* a:(text space+ otherText)+ newLine*

وعندما لا تكون التسمية ذات مغزى خاص ، اسمح أيضًا بهذا:

rule = space* :(text space+ otherText)+ newLine*

لذا تخطي اسم التصنيف تمامًا.

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

+1 لـ @ - هذا يتكرر كثيرًا في جميع أنحاء الكود الخاص بي.

+1 للحصول على طريقة موجزة للقيام بذلك.

يبدو أن هذا الألم مشابه لما يحدث في بناء الجملة المطول function في JS ، والذي يعالج ES6 باستخدام وظائف الأسهم . ربما يمكن استخدام شيء مماثل هنا؟ شيء مثل:

rule = (space* a:(text space+ otherText) newLine*) => a

يبدو لي أن هذا مرن جدًا ، ولا يزال صريحًا (قلق lawildeyes ) ، ولا يبدو أنه يضيف تعقيدًا لأنه في كل من التركيب والتنفيذ ينسجم مع JS الأساسي ...

كنت أتخيل شيئًا مثل:

additive = left:multiplicative "+" right:additive {= left + right; }

حيث يتم تحويل = (لا تتردد في مناقشة اختيار الشخصية) كأول حرف ليس بمسافة بيضاء في الكتلة إلى return .

قد يعمل هذا أيضًا مع التعبيرات الكاملة ويجب أن يكون ممكنًا مع مرور التحويل.

أى اخبار؟ لماذا لا additive = left:multiplicative "+" right:additive { => left + right } ؟

سيبدو الأمر بديهيًا بالتأكيد نظرًا لكيفية عمل وظائف السهم الآن ( (left, right) => left + right ).

يوجد في الواقع عدد غير قليل من الأمثلة على الأماكن في ملف parser.pegjs التي يمكن تحسينها بواسطة هذه الميزة.

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

  = head:ActionExpression tail:(__ "/" __ ActionExpression)* {
      return tail.length > 0
        ? {
            type: "choice",
            alternatives: buildList(head, tail, 3),
            location: location()
          }
        : head;
    }

هش بسبب الرقم السحري 3 في استدعاء buildList الذي لا يرتبط بشكل حدسي بموضع ActionExpression الخاص بك في التسلسل. تعتبر وظيفة buildList نفسها معقدة من خلال الجمع بين عمليتين مختلفتين. باستخدام التعبير @ وصيغة الانتشار es6 ، يصبح هذا أكثر نظافة:

  = head:ActionExpression tail:(__ "/" __ @ActionExpression)* {
      return tail.length > 0
        ? {
            type: "choice",
            alternatives: [head, ...tail],
            location: location()
          }
        : head;
    }

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

  = ExtractSequenceExpression
  / expression:SequenceExpression code:(__ CodeBlock)? {
      return code !== null
        ? {
            type: "action",
            expression: expression,
            code: code[1],
            location: location()
          }
        : expression;
    }

ExtractExpression
  = "@" __ expression:PrefixedExpression {
      return {
        type: "labeled",
        label: "value",
        expression: expression,
        location: location()
      };
    }

ExtractSequenceExpression
  = head:(__ PrefixedExpression)* _ extract:ExtractExpression tail:(__ PrefixedExpression)* {
      return {
        type: "action",
        expression: {
          type: "sequence",
          elements: extractList(head, 1).concat(extract, extractList(tail, 1)),
          location: location()
        },
        code: "return value;",
        location: location()
      }
    }

لقد تحققت من جوهر يوضح كيف سيتم تبسيط parser.pegjs باستخدام التدوين @.

تمت إزالة وظائف extractOptional و extractList و buildList تمامًا ، نظرًا لأن التدوين @ يجعل استخراج القيم المرغوبة من التسلسل أمرًا بسيطًا.

https://gist.github.com/krisnye/a6c2aac94ffc0e222754c52d69e44b83

krisnye إليك كيف سيبدو إذا كان هناك المزيد من السكر

https://github.com/polkovnikov-ph/newpeg/blob/master/parse.np

أفكر في استخدام مزيج من :: و # لميزة بناء الجملة هذه (انظر الشرح / السبب في # 545 ):

  • عامل الربط ::
  • عامل التوسيع #
// this is imported into grammar
class List extends Array {
  constructor() { this.isList = true; }
}

// grammar
number = _ ::value+ _
value = ::int #(_ "," _ ::int)* { return new List(); }
int = $[0-9]+
_ = [ \t]*
  • في تسلسل جذر القاعدة ، سيعيد :: نتيجة التعبير كنتيجة للقواعد
  • في تسلسل متداخل ، سيعيد :: نتيجة التعبير المتداخل كنتيجة التسلسلات
  • إذا تم استخدام أكثر من :: ، فسيتم إرجاع نتيجة التعبيرات المميزة كمصفوفة
  • إذا تم استخدام # في تسلسل متداخل يحتوي على :: ، فسيتم دفع النتائج إلى مصفوفة الأصل
  • إذا كانت القاعدة تحتوي على كتلة رمز مع :: / # ، فقم بتنفيذها أولاً ، ثم استخدم النتائج push طريقة

باتباع هذه القواعد ، سيؤدي تمرير 09 , 55, 7 إلى المحلل اللغوي الذي تم إنشاؤه في المثال أعلاه إلى:

result = [
    isList: true
    0: "09"
    1: "55"
    2: "7"
]

result instanceof Array # true in ES2015+ enviroments
result instanceof List # true

في تسلسل جذر القاعدة ، سيعيد :: نتيجة التعبير كنتيجة للقواعد
في تسلسل متداخل ، سيعيد :: نتيجة التعبير المتداخل كنتيجة التسلسلات

لماذا هذه منفصلة؟ لماذا لا يكون " :: في التسلسل فقط هو نتيجة وسيطة نتيجة التسلسل"؟

إذا تم استخدام أكثر من واحد :: ، فسيتم إرجاع نتيجة التعبيرات المحددة كمصفوفة.

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

إذا تم استخدام # في تسلسل ، فستكون النتائج Array # concat'ed في مصفوفة الأصل

الآن هذه فكرة مروعة. من الواضح أن هذا يعد بمثابة خدعة للتخلص من الدخيلة { return xs.push(x), xs } . إنشاء مثل هذه الحالة الخاصة ليس له أي معنى ، لأنه يمكن حلها بطريقة عامة باستخدام قواعد معلمات. ليس هناك الكثير من متواليات الأحرف المفردة لاستخدامها في المشغلين ، ولا ينبغي لنا إهدارها.

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

إذن ، يجب أن يحتوي f = ::"a" { return "b" } على ["a", "b"] نتيجة لذلك؟

يمر 09. 55: 7 إلى المحلل اللغوي الذي تم إنشاؤه في المثال أعلاه ينتج عنه:

لن يكون الأمر كذلك ، لم يتم ذكر أي من . أو : . لا أرى كيف يمكن أن يؤدي السلوك الموصوف إلى النتيجة أيضًا.

الرقم = _ :: القيمة + _

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

start = _ value
value = ::int #("," _ ::int)* { return new List(); }
number = ::$[0-9]+ _
_ = [ \t]*

مثال على الفئات التي تم تنفيذها في مثال JavaScript (لا يُقصد بها أن تكون تطبيقًا حقيقيًا):

ClassMethod
  = head:FunctionHead __ params:FunctionParameters __ body:FunctionBody {
      return {
        type: "method",
        name: head[ 1 ],
        modifiers: head[ 0 ],
        params: params,
        body: body
      };
    }

// `::` inside the zero_or_more "( ... )*" builds an array as we want,
// so this rule returns `[FunctionModifier[], Identifier]` as expected
MethodHead = (::MethodModifier __)* ("function" __)? ::Identifier

// https://github.com/tc39/proposal-class-fields#private-fields
MethodModifier
  = "#"
  / "static"
  / "async"

FunctionParameters
  = "(" __ head:FunctionParam tail:(__ "," __ ::FunctionParam)* __ ")" {
      // due to `::`, tail is `FunctionParam[]` instead of `[__, "", __, FunctionParam][]`
      return [ head ].concat( tail );
    }
    / "(" __ ")" { return []; }

FunctionParam
  = name:Identifier value:(__ "=" __ ::Expression)? {
      return { name, value };
    }

FunctionBody = "{" __ ::SourceElements? __ "}"

لماذا هذه منفصلة؟ لماذا لا ينتج فقط :: المتوالية نتيجة وسيطة نتيجة التسلسل "؟

أليس هذا نفس الشيء؟ لقد أوضحت الأمر بشكل أكثر وضوحًا حتى يمكن فهم نتيجة حالات الاستخدام المختلفة مثل MethodHead و FunctionParam و FunctionBody بسهولة.

لا معنى لدمج قيم من عدة أنواع في مصفوفة. (قد يكون هذا عبارة عن مجموعة ، لكنها غير مجدية إلى حد كبير في JS.)

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

MethodHead
  = modifiers:(::MethodModifier __)* ("function" __)? name:Identifier {
      return [ modifiers, name ];
    }

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

إذا تم استخدام # في تسلسل ، فستكون النتائج Array # concat'ed في مصفوفة الأصل

الآن هذه فكرة مروعة. من الواضح أن هذا يعد خدعة للتخلص من الدخيلة {return xs.push (x)، xs}

كما أنه يساعد في حالات الاستخدام الأكثر شيوعًا مثل FunctionParameters حيث سيكون من الأفضل كتابة:

// should always return `FunctionParam[]`
FunctionParameters
  = "(" __ ::FunctionParam #(__ "," __ ::FunctionParam)* __ ")"
  / "(" __ ")" { return []; }

يمكن حلها بطريقة عامة باستخدام قواعد معلمات

أعتقد أنه يجب عليّ تنفيذ قيم إرجاع فردية قبل القواعد ذات المعلمات لأنني ما زلت غير متأكد من كيفية المتابعة مع الأحدث (أحب استخدام القوالب ، ولكن يبدو أن استخدام rule < .., .. > = .. يضيف الكثير من الضوضاء إلى قواعد PEG.js ، لذلك أحاول التفكير في تغيير طفيف في بناء الجملة لجعله مناسبًا بشكل أفضل) ، لكن هذه مشكلة منفصلة.

ليس هناك الكثير من متواليات الأحرف المفردة لاستخدامها في المشغلين ، ولا ينبغي لنا إهدارها.

هذا صحيح ، لكن إذا لم نستخدمها عندما يكون هذا الحدث هو نفسه ، فهذا سيء تمامًا.

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

إذن ، يجب أن يحتوي f = ::"a" { return "b" } على ["a", "b"] نتيجة لذلك؟

لا ، حيث يتوقع المحلل اللغوي أن يقوم مقطع الشفرة بإرجاع كائن يشبه المصفوفة يحتوي على طريقة push (لذلك سيكون f = ::"a" { return [ "b" ] } إرجاع [ "b", "a" ] كنتيجة لذلك) ، لذلك يسمح بالدفع ليس فقط إلى المصفوفات ، ولكن العقد المخصصة التي لها نفس الطريقة المطبقة للعمل بطريقة مماثلة. بالنظر إلى أن هذا كان أول قطار تفكير لك بعد قراءة ذلك ، هل سيكون من الأفضل أن تفهم ما إذا كان هذا وراء خيار مثل pushSingleReturns ؟ إذا كان هذا الخيار هو false (افتراضي) ، فإن وجود مقطع رمز بعد تسلسل يحتوي على قيم إرجاع فردية قد يؤدي إلى حدوث خطأ.

يمر 09. 55: 7 إلى المحلل اللغوي الذي تم إنشاؤه في المثال أعلاه ينتج عنه:

لن يكون الأمر كذلك ، لم يتم ذكر . أو : .

عذرًا ، كان هذا خطأً تركته عندما أعدت كتابة المثال المحدد.

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

أعتقد أن هذه مجرد مسألة تفضيل حقًا: ابتسم: على الرغم من أنني أعتقد أنه كان من الأسهل فهم هذا المثال:

number = _ ::value+ EOS
...
EOS = !.

لا أرى كيف يمكن أن يؤدي السلوك الموصوف إلى النتيجة أيضًا.

هل يساعد هذا التعليق المحدث في فهم ما أحاول قوله ، وإذا لم يكن الأمر كذلك ، فما الذي لا تفهمه.

أتفق مع @ polkovnikov-ph على أن التغييرات المعروضة حسب الأماكن غير واضحة للغاية وستكون مجرد مصدر لأخطاء إضافية.

إذا تم استخدام # في تسلسل ، فستكون النتائج Array # concat'ed في مصفوفة الأصل

ما الذي يجب إرجاعه في القواعد النحوية start = #('a') ؟ بقدر ما أفهم ، فكر في كيفية تركيب السكر للمصفوفات المسطحة؟ لا أعتقد أن هذا المشغل ضروري. من أجل الاستخدام الأكثر وضوحًا - تعبيرات قوائم الأعضاء بالفواصل - من الأفضل إنشاء البنية الخاصة (انظر # 30 والشوكة الخاصة بي ، https://github.com/Mingun/pegjs/commit/db4b2b102982a53dbed1f579477c85c06f8b92e6).

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

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

بقيت النقاط الثلاث التي تمكنت من وصفها حتى بدأ إحساسها الواضح في الهروب. ما مدى صحة note @ polkovnikov-ph لماذا كان في الوصف لفصل الحالة الأولى عن الحالة الثانية؟ يتم تنفيذ قاعدتين بسيطتين فقط:

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

أمثلة:

start =   'a' 'b'   'c'; // => ['a', 'b', 'c']
start = ::'a' 'b'   'c'; // => 'a'
start = ::'a' 'b' ::'c'; // => ['a', 'c']

يصف المثال الكبير بالضبط ما كنت أتوقع رؤيته من :: ولا يصف حالات الاستخدام المشكوك فيها ( # ، عدة :: ).

أليس هذا نفس الشيء؟

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

في رأيي ، سيؤدي ذلك إلى تبسيط حالات الاستخدام مثل MethodHead

لكن لماذا لا تصنع كائنًا بدلاً من ذلك؟ هناك علامات modifiers: و name: ، اتركها كما هي في كائن JS الناتج ، وسيكون ذلك رائعًا.

كما أنه يفتح إمكانية ارتكاب المطور لخطأ (إما في الطريقة التي ينفذون بها قواعدهم النحوية ، أو في كيفية معالجة النتائج من خلال الإجراءات)

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

كما أنه يساعد في حالات الاستخدام الأكثر شيوعًا مثل FunctionParameters حيث سيكون من الأفضل كتابة:

لكن هذا هو نفس الشيء. سيكون التركيب اللطيف حقًا هو inter(FunctionParam, "," __) ، مع

inter a b = x:a xs:(b ::a)* { return xs.unshift(x), xs; }

القاعدة <.. ، ..> = .. يبدو أنها تضيف الكثير من الضجيج لقواعد PEG.js

يتوقع الناس أن يتم استخدام <...> للأنواع ، بينما في هذه الحالة لا تكون الوسائط من الأنواع. أفضل طريقة هي طريقة Haskell بدون أي أحرف إضافية على الإطلاق (انظر inter أعلاه). لست متأكدًا من كيفية تفاعل ذلك في قواعد PEG.js مع حذف ; . قد تكون هناك حالة عندما يتم تضمين f a b = ... (جزئيًا) في الصف السابق.

تُستخدم كعامل توسع في بعض اللغات التي تنفذ توجيهات ما قبل المعالجة

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

f = type:#"ident" name:$([a-z]i [a-z0-9_]i+)

ستعيد {type: "ident", name: "abc"} للإدخال "abc" .

لا ، حيث يتوقع المحلل اللغوي أن تقوم كتلة التعليمات البرمجية بإرجاع كائن يشبه المصفوفة يحتوي على طريقة دفع (لذلك سيكون f = :: "a" {return ["b"]} إرجاع ["b"، " أ "] نتيجة) ،

O_O

أعتقد أن هذه مجرد مسألة تفضيل حقًا

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

Mingun أعتقد أن @ futagoza يستكشف مساحة التصميم. هذا أمر جيد ، خاصة إذا كان علنيًا ولدينا فرصة للاختلاف :)

الشيء الرئيسي الذي يجب أن تفعله هو ألا تسأل "لماذا" بل أن تقول "لا! ليس هكذا!"

image

f = type:#"ident" name:$([a-z]i [a-z0-9_]i+) سيعود {type: "ident", name: "abc"} للإدخال "abc" .

من فضلك لا ، هاها. هذه الصيغة _wayyy_ سحرية للغاية.

أعتقد أن عامل التشغيل المقترح أصلاً @ مثالي كما هو. مرات عديدة واجهت مشكلة التسلسل:

sequence
    = first:element rest:(whitespace next:element {return next;})*
    {
        return [first].concat(rest);
    }
    ;

_مثل هذا _ صعوبة الكتابة مرارًا وتكرارًا ، خاصةً عندما تكون أكثر تعقيدًا من ذلك.

ومع ذلك ، مع عامل التشغيل @ ، يصبح ما سبق ببساطة:

sequence = first:element rest:(whitespace @element)* { return [first].concat(rest); };

وباستخدام إما https://github.com/pegjs/pegjs/issues/235#issuecomment -66915879 أو https://github.com/pegjs/pegjs/issues/235#issuecomment -67544080 الذي يتم تقليله إلى:

sequence = first:element rest:(whitespace @element)* => [first].concat(rest);
/* or */
sequence = first:element rest:(whitespace @element)* {=[first].concat(rest)};

... الأول الذي أنا متحيز جدًا له.

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

في الواقع ، إذا لم أكن مخطئًا ، فقد يكون مجرد نتوء بسيط. قد يكون هناك شيء للتفكير فيه لـ 0.11.0futagoza.

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

لقد بدأت في تنفيذ هذا بمفردي منذ فترة ، لكنني أسقطته حتى الآن (عندما كان يجب أن أفعل # 579 بدلاً من ذلك 😆) واعتمدت منشئ الرمز الثانوي على تطبيق Mingun (https://github.com/Mingun/pegjs/commit/1c1c852bae91868eaa90d9bd9f7e4f722aa6435e )

يمكنك تجربته هنا: https://pegjs.org/development/try (المحرر عبر الإنترنت ، ولكن باستخدام PEG 0.11.0-dev)

حان وقت التسليم يا باتمان. عمل رائع futagoza ، لقد dev على npm بالفعل؟ أود أن أبدأ الاختبار معها.

لأي شخص يريد أن يجربها بقواعد نحوية أساسية ، ضع هذا الجرو هناك وامنحه مدخلات مثل "abcd" .

foo
    = '"' @$bar '"'
    ;

bar
    = [abcd]*
    ;

هل تم إصدار هذا لعلامة dev على npm بالفعل؟

https://www.npmjs.com/package/pegjs/v/0.11.0-dev.325

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

تم دمج هذه التذكرة

pattern:Pattern init:(_ "=" _ <strong i="7">@a</strong>:AssignmentExpression)?

نفس الشيء في es6 ، والذي يفهمه الجميع بطبيعته ، والذي يأتي مجانًا عند الانتهاء من الأجزاء الأخرى من المحلل اللغوي ، هو

pattern:Pattern init:(_ "=" _ a:AssignmentExpression)? => a

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

الرجاء إعادة فتح هذه المشكلة ، futagoza ، حتى يتم إصلاح ذلك في إصدار تم إصداره

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