سؤال

أحاول بناء قواعد Lisp.الحق سهلة؟على ما يبدو لا.

أقدم هذه المدخلات وأتلقى الأخطاء ...

( 1 1)
23 23 23 
ui ui

هذا هو النحو...

%%
sexpr: atom                 {printf("matched sexpr\n");}
    | list
    ;
list: '(' members ')'       {printf("matched list\n");}
    | '('')'                {printf("matched empty list\n");}
    ;
members: sexpr              {printf("members 1\n");}
    | sexpr members         {printf("members 2\n");}
    ;
atom: ID                    {printf("ID\n");}
    | NUM                   {printf("NUM\n");}
    | STR                   {printf("STR\n");}
    ;
%%

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

تحرير - كان هذا هو أسلوبي "المحطة العليا":

program: slist;

slist: slist sexpr | sexpr;

لكنه يسمح بمشاكل مثل:

( 1 1 

تحرير 2:كود الفليكس هو...

%{
    #include <stdio.h>
    #include "a.yacc.tab.h"
    int linenumber;
    extern int yylval;
%}
%%
\n                         { linenumber++; }
[0-9]+                     { yylval = atoi(yytext); return NUM; }
\"[^\"\n]*\"               { return STR; }
[a-zA-Z][a-zA-Z0-9]*       { return ID; }
.
%%

مثال على التطابق الزائد...

(1 1 1)
NUM
matched sexpr
NUM
matched sexpr
NUM
matched sexpr
(1 1
NUM
matched sexpr
NUM
matched sexpr

ما الخطأ هنا؟

يحرر:الخطأ كان في lexer.

هل كانت مفيدة؟

المحلول

الخطأ حقا في المعجم.قوسينك ينتهي بهم المطاف إلى آخر ". في Lexer ، ولا تظهر كأقواس في المحلل.

إضافة قواعد مثل

\)     { return RPAREN; }
\(     { return LPAREN; }

إلى المعجم وتغيير كافة تكرارات '(',')' إلى LPAREN وRPAREN على التوالي في المحلل اللغوي.(تحتاج أيضًا إلى #define LPAREN وRPAREN حيث تحدد قائمة الرموز المميزة الخاصة بك)

ملحوظة:لست متأكدًا من بناء الجملة، ربما تكون الخطوط المائلة العكسية خاطئة.

نصائح أخرى

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

إذا كان الهدف هو تحليل مجموعة فرعية من لثغة، ثم نص البرنامج عبارة عن سلسلة من sexprs.

وكنت على صواب في أن تحتاج إلى تعريف غير المحطة. التي من شأنها أن تكون على النحو المحدد مجموعة من sexpr. لست متأكدا من بناء الجملة YACC لذلك. أنا جزئي ل ANTLR للحصول على مولدات محلل وسيكون بناء الجملة على النحو التالي:

program: sexpr*

ومبينا 0 أو أكثر sexpr.

وتحديث مع تركيب YACC:

program :  /* empty */
        | program sexpr
        ;

وليس في YACC، ولكن قد تكون مفيدة على أي حال، وهنا النحوي الكامل في V3 ANTLR الذي يعمل في الحالات وصفت لكم (باستثناء السلاسل في lexer لأنه ليس من المهم في هذا المثال، يستخدم أيضا C # وحدة الإخراج لأن هذا هو ما أنا اختباره مع):

program: (sexpr)*;

sexpr: list
    |  atom            {Console.WriteLine("matched sexpr");}
    ;

list:     
   '('')'              {Console.WriteLine("matched empty list");}
   | '(' members ')'   {Console.WriteLine("matched list");}

    ;

members: (sexpr)+      {Console.WriteLine("members 1");};

atom: Id               {Console.WriteLine("ID");}
    | Num              {Console.WriteLine("NUM");}
    ;


Num: ( '0' .. '9')+;
Id: ('a' .. 'z' | 'A' .. 'Z')+;
Whitespace : ( ' ' | '\r' '\n' | '\n' | '\t' ) {Skip();};

وهذا لن ينجح تماما كما هو في YACC لYACC يولد ومحلل LALR بينما ANTLR هو أصل متكررة تعديلها. وهناك هدف إخراج C / C ++ لANTLR إذا أردت للذهاب إلى هذا الطريق.

هل neccesarily بحاجة إلى ياك / محلل البيسون؟ A "يقرأ مجموعة فرعية من جملة ثغة" القارئ ليس من الصعب تنفيذها في C (تبدأ مع وظيفة read_sexpr، وإيفاد لread_list عند رؤية '('، وهذا بدوره يبني قائمة sexprs الواردة حتى " ) "وينظر، وإلا، استدعاء read_atom الذي يجمع ذرة ويعود ذلك عندما لم تعد قادرة على قراءة الحروف ذرة التأسيسية)

ومع ذلك، إذا كنت تريد أن تكون قادرة على قراءة اللثغة المشتركة arbritary، ستحتاج إلى (في أسوأ) تنفيذ اللثغة المشتركة، كما يمكن تعديل CL القارئ وقت التشغيل (وحتى التبديل بين مختلف قراءة الجداول وقت التشغيل تحت السيطرة برنامج؛ مفيد جدا عندما كنت ترغب في تحميل قانون مكتوب في لغة أو لهجة من لثغة آخر)

ولقد مضى وقت طويل منذ أن عملت مع YACC، ولكنك في حاجة إلى المستوى الأعلى غير المحطة. هل يمكن أن يكون أكثر تحديدا عن "حاولت" و "لا يبدو للعمل"؟ أو، لهذه المسألة، ما هي الأخطاء؟

وكنت أيضا أظن أن YACC قد تكون مبالغة لمثل هذه اللغة في بناء الجملة ضوء. شيء أكثر بساطة (مثل النسب العودية) قد تعمل على نحو أفضل.

هل يمكن أن تحاول هذه القواعد هنا .

ولقد حاولت ذلك، يا "قواعد ياك ثغة" يعمل على ما يرام:

%start exprs

exprs:
    | exprs expr
    /// if you prefer right recursion :
    /// | expr exprs
    ;

list:
    '(' exprs ')'
    ;

expr:
    atom
    | list
    ;

atom:
    IDENTIFIER
    | CONSTANT
    | NIL
    | '+'
    | '-'
    | '*'
    | '^'
    | '/'
    ;
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top