Lex - не обнаруживает токен после добавления новой строки - PullRequest
0 голосов
/ 08 января 2019

Я пытаюсь написать программу, которая читает действие и его компоненты из файла PDDL . Сначала программа должна искать токен :action(, а затем action name и т. Д.

Ниже приведен мой лекс-код:

Примечание. Ответ на этот вопрос в основном связан с токеном :(action, токеном action name и токеном newline, поэтому вы можете посмотреть только на них. Под SC_ACNAME я имею в виду имя действия сканирования и т. Д.

%{
#include "myscanner.h"
%}

%START SC_ACNAME SC_PARAMETERS SC_PREDICATE SC_BODY

NAME                                [0-9a-zA-Z_\-]+
TEXT                                [0-9a-zA-Z?_\-( \t]+
TEXT_PARAM                          [0-9a-zA-Z?_\-( \t\n]+
TEXTBREAK                           [ \t\n]+

    int lb_flag=0;
    int pred_lb_flag = 0;

%%

\(:action                                                               {lb_flag++; BEGIN SC_ACNAME; return ACTION;}
<SC_ACNAME>{TEXT}                                                       {BEGIN SC_BODY; return ACTION_NAME;}
<SC_BODY>:parameters                                                    {BEGIN SC_PARAMETERS; return PARAMETER;}
<SC_PARAMETERS>{TEXT_PARAM}                                             {lb_flag++; BEGIN SC_BODY; return PARAMETERS;}  
<SC_BODY>:precondition                                                  {BEGIN SC_PREDICATE; return PRECONDITION;}
<SC_BODY>:effect                                                        {BEGIN SC_PREDICATE; return EFFECT;}
<SC_PREDICATE>\(and                                                     {pred_lb_flag++; return CONJUNCTION;}
<SC_PREDICATE>\(not                                                     {pred_lb_flag++; return NEGATION;}
<SC_PREDICATE>\({NAME}({TEXTBREAK}\?{NAME})+\)                          return PREDICATE;
<SC_PREDICATE>\)                                                        {if(pred_lb_flag) pred_lb_flag--; if(!pred_lb_flag) BEGIN SC_BODY; return RIGHT_BRACKET;}
<SC_BODY>\)                                                             {if(lb_flag) lb_flag--; if(!lb_flag) BEGIN 0; return RIGHT_BRACKET;}
<SC_PREDICATE,SC_BODY,SC_ACNAME>{TEXTBREAK}                             ;   

%%

int yywrap(void)
{
    return 1;
}

Заголовочный файл (myscanner.h):

#define ACTION 1
#define ACTION_NAME 2
#define PARAMETER 3
#define PARAMETERS 4
#define PRECONDITION 5
#define EFFECT 6
#define CONJUNCTION 7
#define NEGATION 8
#define PREDICATE 9
#define RIGHT_BRACKET 10

В моей C-программе:

#include <stdio.h>
#include "myscanner.h"

extern int yylex();
extern int yylineno;
extern char* yytext;

int main(void)
{
    int ntoken, vtoken;

    ntoken = yylex();
    while(ntoken)
    {
        printf("%d", ntoken);
        print("%s", yytext);
        ntoken = yylex();
    }
    return 0;
}

Когда я пытаюсь токенизировать файл, который содержит (:action move, он обнаруживает :(action и action name по желанию и возвращает ACTION и ACTION_NAME. Но когда я ввожу символ новой строки после перемещения (имя действия), он ничего не обнаруживает. Почему он не распознает токен (:action?

РЕДАКТИРОВАТЬ:

Пройти тестовый кейс: domain.pddl

(:action move

Тестовый пример отказа: domain.pddl

(:action move<nl>

обозначает перевод строки

1 Ответ

0 голосов
/ 08 января 2019

Я рекомендую вам добавить, например, putchar('\n'); перед return 0; in main , чтобы очистить то, что производит printf , может быть, у вас ничего не напечатано из-за этого промаха

Если 'f' содержит строку (:action move<nl>, и я выполняю a.out < f, которая печатает 1(:action2 move, и то же самое, если строка не заканчивается на 'f' (нет в конце)

...