سؤال

مع القواعد التالية، أحصل على خطأ في بناء الجملة مع هذا النوع من المدخلات:

ls /home > foo #Runs and works okay, but raises error token
ls /home /foo /bar /etc #works okay

أعتقد أنه قد يكون له شيء ما يتعلق بكيفية أعمال البحث، ولكن هذا هو أول قواعدي وأربط قليلا عن سبب عدم العمل بهذه الطريقة: Word Word external_cmd GT هو إعادة توجيه، إعادة توجيه هو أمر، الأمر هو أوامر، لذلك يجب أن تعمل أوامر الإدخال Newline.

القواعد العليا للقواعد:

input:
    error NEWLINE {
        printf("Error Triggered\n");
        yyclearin;
        yyerrok; 
        prompt(); 
    } |
    input NEWLINE {
        prompt();
    } | 
    input commands NEWLINE {
        prompt (); 
    } | 
    /* empty */
    ;   

commands: 
    command |   
    command SEMI | 
    command SEMI commands
    ;   

command:
    builtin_cmd |
    redirect |
    external_cmd { 
        execute_command($1, 0, NULL);
    }
    ;

redirect:
    external_cmd GT WORD  {
        printf("Redirecting stdout of %s to %s\n", $1->cmd, $3);
        //printf("DEBUG: GT\n");
        execute_command($1, STDOUT_FILENO, $3);
    }
    external_cmd LT WORD {
        printf("Redirecting stin of %s to %s\n", $1->cmd, $3);
        //printf("DEBUG: GT\n");
        execute_command($1, STDIN_FILENO, $3);
    }
    ;

مدخلات Debug / Verbose عند رفع رمز الخطأ:

Next token is token WORD ()
Shifting token WORD ()
Entering state 6
Reading a token: Next token is token WORD ()
Shifting token WORD ()
Entering state 24
Reading a token: Next token is token GT ()
Reducing stack by rule 22 (line 115):
   $1 = token WORD ()
-> $$ = nterm arg_list ()
Stack now 0 2 6
Entering state 26
Reducing stack by rule 19 (line 91):
   $1 = token WORD ()
   $2 = nterm arg_list ()
-> $$ = nterm external_cmd ()
Stack now 0 2
Entering state 16
Next token is token GT ()
Shifting token GT ()
Entering state 29
Reading a token: Next token is token WORD ()
Shifting token WORD ()
Entering state 33
Reducing stack by rule 11 (line 68):
Redirecting stdout of ls to foo
DEBUG: redirect mode is 1
DEBUG: Command to run is ls
DEBUG: Adding Argument /home
admin  kbrandt  tempuser
-> $$ = nterm @1 ()
Stack now 0 2 16 29 33
Entering state 34
Reading a token: Next token is token NEWLINE ()
syntax error
Error: popping nterm @1 ()
Stack now 0 2 16 29 33
Error: popping token WORD ()
Stack now 0 2 16 29
Error: popping token GT ()
Stack now 0 2 16
Error: popping nterm external_cmd ()
Stack now 0 2
Error: popping nterm input ()
Stack now 0
Shifting token error ()
Entering state 1
Next token is token NEWLINE ()
Shifting token NEWLINE ()
Entering state 3
Reducing stack by rule 1 (line 38):
   $1 = token error ()
   $2 = token NEWLINE ()
Error Triggered
-> $$ = nterm input ()
Stack now 0
Entering state 2

تحديث:
external_cmd هو:

external_cmd:
    WORD arg_list {
        $$ = malloc( sizeof(struct ext_cmd) );
        if ( $$ == NULL)
            printf("Memory Allocation Error\n");
        $$->cmd = $1;
        $$->args_pp = $2;
    } |
    WORD    {
        $$ = malloc( sizeof(struct ext_cmd) );
        if ( $$ == NULL)
            printf("Memory Allocation Error\n");
        $$->cmd = $<string>1;
        $$->args_pp = NULL;
    }
هل كانت مفيدة؟

المحلول 3

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

نصائح أخرى

خطأ بناء الجملة يأتي من دعوة الثانية إلى YYPARESE. عندما يكون لديك إعادة توجيه، تقوم Grammar بإجراء Yyaccept، مما يؤدي إلى العودة المحللين على الفور دون قراءة أي شيء آخر. في الدعوة الثانية، القراءة الرمز المميز الأول هو جديد، والحالات التي حالات الخطأ (لا يسمح قواعدك بإجراء خطوط فارغة.)

مع عدم وجود إعادة توجيه، لا يوجد Yyaccept، وبالتالي فإن القواعد الأساسية تواصل تشغيلها، وقراءة الخط الجديد والعودة إلى الوصول إلى نهاية المدخلات.

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

  2. ما هو بالضبط external_cmdب إنه نوع من يبدو وكأنه يتم تقليله مبكرا ولكن من الصعب أن أقول لأنك لم تشمل ذلك.

  3. لماذا YYACCEPT استدعاء بعد أي إعادة توجيه؟ إذا كنت تنوي إعادة تشغيل المحلل المحلل في كل سطر، فلا يجب أن يكون لديك جامع الإدخال المكرر. طالما أن لديك، لا تفعل yyaccept.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top