Бизон говорит, что начальный символ не выводит никакого предложения - PullRequest
0 голосов
/ 27 декабря 2018

Я пишу базовый компилятор и рано застрял.Когда я пытаюсь запустить мой файл зубров, он выдает ошибку (это ниже), я понятия не имею, почему это происходит, и боролся с этим в течение достаточно долгого времени.

ОШИБКА:

compiler/parser.y: warning: 9 nonterminals useless in grammar [-Wother]
compiler/parser.y: warning: 32 rules useless in grammar [-Wother]
compiler/parser.y:34.1-7: fatal error: start symbol program does not derive any sentence
 program            :   DECLARE declaration IN commands END

FLEX:

%option noyywrap
%{
    #include <stdio.h>
    #include "parser.tab.h"
%}

NUMBER          [0-9]+
PID                 [_a-z]+

WHITESPACE  [ \t\r]+

%x COMMENT
%%

<INITIAL>{
"["                     BEGIN(COMMENT);

\n                      yylineno++;
{WHITESPACE}

{NUMBER}            {
                                printf("Number: %s\n", yytext);
                                yylval.ival = (char*) strdup(yytext);
                                return NUM;
                            }

{PID}                   {
                                printf("PID: %s\n", yytext);
                                yylval.sval = (char*) strdup(yytext);
                                return PID;
                            }

":="                    return ASSIGN;

"+"                     return ADD;
"-"                     return SUB;
"*"                     return MUL;
"/"                     return DIV;
"%"                     return MOD;

"="                     return EQ;
"!="                    return NEQ;
"<"                     return LT;
">"                     return GT;
"<="                    return LE;
">="                    return GE;

")"                     return R_BRACKET;
"("                     return L_BRACKET;
";"                     return SEMICOLON;
":"                     return COLON;


"DECLARE"           return DECLARE;
"IN"                    return IN;
"END"                   return END;

"IF"                    return IF;
"ELSE"              return ELSE;
"ENDIF"             return ENDIF;

"WHILE"             return WHILE;
"DO"                    return DO;
"ENDWHILE"      return ENDWHILE;
"ENDDO"             return ENDDO;

"FOR"                   return FOR;
"FROM"              return FROM;
"TO"                    return TO;
"DOWNTO"            return DOWNTO;
"ENDFOR"            return ENDFOR;

"READ"              return READ;
"WRITE"             return WRITE;
}

<COMMENT>{
"]"                     BEGIN(INITIAL);
[^\n]+\n            yylineno++;
}

%%

BISON:

%{
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    extern int yylineno;

    int yylex(void);
    void yyerror(const char *);

    int error = 0;
%}

%union{
    char* sval;
    char* ival;
}

%token <sval> DECLARE /* Declarations block */
%token <sval> IN END /* Code block */
%token <sval> IF THEN ELSE ENDIF /* Conditional block */
%token <sval> WHILE DO ENDWHILE ENDDO /* While-do and Do-while loop block */
%token <sval> FOR FROM TO DOWNTO ENDFOR /* For loop block */
%token <sval> READ WRITE
%token <sval> ASSIGN
%token <sval> ADD SUB MUL DIV MOD /* Arithmetic operators */
%token <sval> EQ NEQ LT GT LE GE /* Boolean operators */
%token <sval> L_BRACKET R_BRACKET SEMICOLON COLON /* Symbols */
%token <ival> NUM
%token <sval> PID

%%

program         :   DECLARE declaration IN commands END
                        ;

declaration :   declaration PID SEMICOLON
                        |   declaration PID L_BRACKET NUM COLON NUM R_BRACKET SEMICOLON
                        ;

commands        :   commands command
                        |   command
                        ;

command         :   id ASSIGN expression SEMICOLON
                        |   IF condition THEN commands ELSE commands ENDIF
                        |   IF condition THEN commands ENDIF
                        |   WHILE condition DO commands ENDWHILE
                        |   DO commands WHILE condition ENDDO
                        |   FOR PID FROM value TO value DO commands ENDFOR
                        |   FOR PID FROM value DOWNTO value DO commands ENDFOR
                        |   READ id SEMICOLON
                        |   WRITE value SEMICOLON
                        ;

expression  :   value
                        |   value ADD value
                        |   value SUB value
                        |   value MUL value
                        |   value DIV value
                        |   value MOD value
                        ;

condition       :   value EQ value
                        |   value NEQ value
                        |   value LT value
                        |   value GT value
                        |   value LE value
                        |   value GE value
                        ;

value               :   NUM
                        |   id
                        ;

id                  :   PID
                        |   PID L_BRACKET PID R_BRACKET
                        |   PID L_BRACKET NUM R_BRACKET
                        ;

%%

void yyerror(const char *msg) {
    fprintf(stderr, "Compiling error: %s\n", msg);
}

Если вам интересно, я запускаю функцию main из другого файла, но не думаю, что это проблема.

Ответы [ 2 ]

0 голосов
/ 29 декабря 2018

Обычно, когда бизон говорит это, он жалуется на грамматику, которой вы его кормите.Это сообщение об ошибке означает, что с этой грамматикой невозможно построить правильное предложение, состоящее только из терминальных символов.Ваша грамматика должна быть исправлена, чтобы иметь возможность строить синтаксические деревья , в листьях которых есть только терминальные символы .Если вы проверите это, вы обнаружите, что на самом деле невозможно построить дерево разбора, которое имеет только конечные символы в листьях.Попробуйте и посмотрите сами.Это происходит с этой простой грамматикой.

sentence: '*' sentence
    | '(' sentence ')' ;

вы увидите, что все деревья синтаксического анализа, которые вы строите для sentence, всегда имеют sentence в качестве одного из своих листьев, поэтому невозможно построить правильное предложение втот язык, который имеет только терминальные символы.

Технические подробности вашей конкретной проблемы обсуждаются в другом ответе, поэтому я не буду повторять их здесь (Bison использует первое правило, которое вы пишете в грамматике, для использования в качестве rootсинтаксического дерева, по умолчанию, в вашем случае это declaration, а не программа)

В любом случае, если вы получили эту ошибку, возможно, это не единственная проблема, с которой вы столкнулись.Если вы попробуете bison с опциями --report и --report-file (см. Man-страницу), вы получите более подробную информацию о правиле, которое делает его неудачным.

edit

посмотрев на ваш код, вы расширяете declaration как declaration и больше вещей в во всех альтернативах, которые вы предоставляете для declaration. Это никогда не может генерировать объявление только терминальных символов, поскольку при расширениивсегда есть declaration для расширения.

0 голосов
/ 27 декабря 2018

Ваша грамматика гласит: program, у вас должно быть declaration:

program         :   DECLARE declaration ...

И единственный способ получить объявление - это два правила

declaration :   declaration ...
                    |   declaration ...

Но оба из них требуют, чтобы у вас уже был declaration.Поскольку вы начинаете с нуля, и вы можете получить declaration, только если он у вас уже есть, вы никогда не сможете иметь никаких объявлений.

Поэтому вы никогда не сможете проанализировать program.

...