Почему я получаю разные результаты от лимонного парсера для одного и того же ввода?

Я использую лимон от cmake и затем делаю. Лимон будет генерировать разные shellparser.c от shellparser.y в зависимости от того, как я его вызываю. Я не уверен в деталях, но, по крайней мере, я могу построить проект сейчас.

Проблема в том, что lemon будет генерировать два разных файла в зависимости от того, как вызывался lemon. Если я вызываю лимон из скрипта cmake, то он работает, и полученный файл может быть скомпилирован без ошибок. Но если я просто lemon -s shellparser.y затем в результате shellparser.c не может быть скомпилировано из-за ошибок компилятора.

Эта проблема не блокирует меня, но я хотел бы знать, что это такое. Мой cmake это:

cmake_minimum_required(VERSION 3.0)
project(shell.test)

if (EDITLINE_LIBRARIES AND EDITLINE_INCLUDE_DIRS)
    set (Editline_FIND_QUIETLY TRUE)
endif (EDITLINE_LIBRARIES AND EDITLINE_INCLUDE_DIRS)

find_path(EDITLINE_INCLUDE_DIRS NAMES editline/readline.h)
find_library(EDITLINE_LIBRARIES NAMES edit)

include (FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Editline DEFAULT_MSG
        EDITLINE_LIBRARIES
        EDITLINE_INCLUDE_DIRS)

mark_as_advanced(EDITLINE_INCLUDE_DIRS EDITLINE_LIBRARIES)

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -L/usr/local/include/ -L/usr/include -std=c99 -pedantic-errors -O3 -g -Wall -pedantic -ledit -ltermcap")
include_directories(/usr/local/include/ /usr/include)
link_directories(/usr/lib)
link_directories(/usr/local/lib)
add_executable(shell main.c errors.c util.c shellparser.c)
target_link_libraries(shell edit readline)
add_custom_target(shellparser DEPENDS ${CMAKE_SOURCE_DIR}/shellparser.c)
add_custom_command(OUTPUT ${CMAKE_SOURCE_DIR}/shellparser.c COMMAND lemon -s ${CMAKE_SOURCE_DIR}/shellparser.y DEPENDS ${CMAKE_SOURCE_DIR}/shellparser.y)
add_dependencies(shell shellparser)

Оскорбительная грамматика:

%include
    {
    #include "types.h"

    #include "assert.h"
    }
    %syntax_error { fprintf(stderr, "Syntax error\n"); }
    %token_type { struct SToken* }
    %type expr { int }
    %left PLUS MINUS.
    %left TIMES DIVIDE.
    %left WHILE.
    program ::= expr(A). { printf("Result = %d\n", A); }
    expr(A)::= WHILE LPAR expr(B) RPAR expr(C). {printf("test"); A = B + C; }
    expr(A) ::= expr(B) PLUS expr(C). {A = B + C; }
    expr(A) ::= expr(B) MINUS expr(C). {A = B - C; }
    expr(A) ::= expr(B) TIMES expr(C). {A = B * C; }
    expr(A) ::= expr(B) DIVIDE expr(C).
    {
        if (C != 0)
        {
            A = B / C;
        }
        else
        {
            fprintf(stderr, "divide by 0");
        }
    }
    expr(A) ::= LPAR expr(B) RPAR. { A = B; }
    expr(A) ::= INTEGER(B).
    {
    printf("the result = %s\n", B->token);
        A = B->value;
        printf("Passed argument: %s\n", B->token);
    }

Ошибка компиляции:

$ make
[ 14%] Built target shellparser
Scanning dependencies of target shell
[ 28%] Building C object CMakeFiles/shell.dir/shellparser.c.o
/home/dac/osh/shellparser.c:89:0: error: "YY_NO_ACTION" redefined
 #define YY_NO_ACTION      (YYNSTATE+YYNRULE+2)
 ^
/home/dac/osh/shellparser.c:88:0: note: this is the location of the previous definition
 #define YY_NO_ACTION         37
 ^
/home/dac/osh/shellparser.c:90:0: error: "YY_ACCEPT_ACTION" redefined
 #define YY_ACCEPT_ACTION  (YYNSTATE+YYNRULE+1)
 ^
/home/dac/osh/shellparser.c:87:0: note: this is the location of the previous definition
 #define YY_ACCEPT_ACTION     36
 ^
/home/dac/osh/shellparser.c:91:0: error: "YY_ERROR_ACTION" redefined
 #define YY_ERROR_ACTION   (YYNSTATE+YYNRULE)
 ^
/home/dac/osh/shellparser.c:86:0: note: this is the location of the previous definition
 #define YY_ERROR_ACTION      35
 ^
/home/dac/osh/shellparser.c:288:9: error: expected expression before ‘%’ token
         %%
         ^
/home/dac/osh/shellparser.c:296:9: error: expected expression before ‘%’ token
         %%
         ^
/home/dac/osh/shellparser.c:296:9: error: initializer element is not constant

Но я могу скомпилировать его, если сгенерирую shellparser.c от cmake. Я посмотрел на файл cmake, но я не мог понять, что еще он делает, как обычно lemon -s, Почему это происходит?

0 ответов

Другие вопросы по тегам