野牛总是给出语法错误

时间:2016-10-24 01:51:48

标签: compiler-errors bison

更新 添加' INT'和' STRING'类型到primary_expression解决了许多(不是全部)错误,尽管它不是ANSI C yacc语法的一部分。哦,好吧,我现在必须到期。

我正在编写编译器并且在我的生活中,我无法确定为什么这个语法给我一个语法错误。任何能够发现这里发生了什么的人都将不胜感激。这是语法

%locations
%defines
%token-table
%union {
    int value;
    char symbol;
    char *str;
};
%{
    #include <iostream>
    #include <string>
    #include <cstdlib>

    using namespace std;

    int yylex();
    int yyparse(void);
    void yyerror(const char *str);
    void lyyerror(YYLTYPE t, char *str, ...);

    extern FILE *yyin;


%}


%start program
%type <value> type
%type <value> compound_instruction
%type <value> instruction
%type <value> expression_instruction
%type <value> iteration_instruction
%type <value> select_instruction
%type <value> jump_instruction
%type <value> expression
%type <value> assignment
%type <value> instruction_list
%type <value> cond_instruction
%type <value> condition
%type <value> expression_additive
%type <value> expression_multiplicative
%type <value> unary_expression
%type <value> expression_postfixee
%type <value> primary_expression



%token INT
%token STRING
%token CONST_INT
%token CONST_STRING

%token IDENT

%token EXTERN

%token IF
%token ELSE
%token WHILE
%token DO
%token RETURN
%token FOR
%token THEN

%token ASSIGNMENT
%token LESSTHAN
%token EQUAL
%token GREATERTHAN
%token LESSTHANEQUAL
%token GREATERTHANEQUAL
%token DIFF

%left PLUS
%left MINUS
%left MULTI
%left DIV

%left SHIFTRIGHT
%left SHIFTLEFT
%left MODULO

%%
program :
external-declaration
| program external-declaration
;

external-declaration :
declaration          // Declaration Global
| EXTERN declaration // Set Extern attribute
| function-definition
;

function-definition :
type function_declarator decl_glb_fct compound_instruction
// generate code function
;

decl_glb_fct :
// Get function name - Create a spot to store the function - set attributes
;

declaration :
type declarator_list ';'
;

type :
INT                     // set INT
| STRING                // set String
;

declarator_list :
declarator              // Propagate code
| declarator_list ',' declarator
;

declaration_list :
declaration                 // Set locals
| declaration_list declaration      // Set locals
;

declarator :
IDENT                   // Create Variable
| function_declarator               // Create Function
;

function_declarator :
IDENT '(' ')'               // Create function name
| IDENT '(' parameter_list ')'      // Create partial function
;

parameter_list :
parameter_declaration
| parameter_list ',' parameter_declaration // Insert parameters
;

parameter_declaration :
type IDENT              // Type declaration
;

instruction :
';'
| compound_instruction {$$=$1;}
| expression_instruction  {$$=$1;}
| iteration_instruction  {$$=$1;}
| select_instruction  {$$=$1;}
| jump_instruction {$$=$1;}
;

expression_instruction :
expression ';'
| assignment ';'
;

assignment :
IDENT ASSIGNMENT expression
;

compound_instruction :
block_start declaration_list instruction_list block_end {$$=$3;}
| block_start declaration_list block_end
| block_start instruction_list block_end {$$=$2;}
| block_start block_end
;


block_start :
'{'  // Init your hash table - symbol table
;

block_end :
'}' // Empty hash table
;

instruction_list :
instruction  {$$=$1;}
| instruction_list instruction {$$=$2;}
;

select_instruction :
cond_instruction instruction
| cond_instruction instruction ELSE instruction
;

cond_instruction :
IF '(' condition ')' {$$=$3;}
;

iteration_instruction :
WHILE '(' condition ')' instruction // Handle while loop
| DO instruction WHILE '(' condition ')'
| FOR '(' assignment ';' condition ';' assignment ')' instruction
;

jump_instruction:
RETURN expression ';'
;

condition :
expression comparison_operator expression
;

comparison_operator :
EQUAL
| DIFF
| LESSTHAN
| GREATERTHAN
| LESSTHANEQUAL
| GREATERTHANEQUAL
;

expression :
expression_additive {$$=$1;}
| expression SHIFTLEFT expression_additive //  Compute expression
| expression SHIFTRIGHT expression_additive // Compute expression
;

expression_additive :
expression_multiplicative {$$=$1;}
| expression_additive PLUS expression_multiplicative // Compute expression
| expression_additive MINUS expression_multiplicative // Compute expression
;

expression_multiplicative :
unary_expression{$$=$1;}
| expression_multiplicative MULTI unary_expression
| expression_multiplicative DIV unary_expression
| expression_multiplicative MODULO unary_expression
;

unary_expression:
expression_postfixee {$$=$1;}
| MINUS unary_expression
;

expression_postfixee :
primary_expression {$$=$1;}
| IDENT '(' argument_expression_list')'
| IDENT '(' ')'
;

argument_expression_list:
expression
| argument_expression_list',' expression
;

primary_expression :
IDENT
| CONST_INT
| CONST_STRING
| '(' expression ')'
;
%%

这是lex文件。

%option noyywrap
%option stack
%option yylineno
%s COMMENT
%s MACRO
%s ENDOFLINE
%s DEFINE
%s STRING
%{
    #include "calc2.tab.hpp"

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <string>
    #include <iostream>

    //#define YY_DECL extern "C" int yylex()
    //#define YYSTYPE int
    //extern YYSTYPE yylval;

    #define YY_USER_ACTION

    extern YY_BUFFER_STATE yy_scan_string(const char *str);

    yy_buffer_state* main_buffer = 0;
    yy_buffer_state* expansion_buffer = 0;

    std::string var,bar,biz;
%}
%%
[ \t\n]+
^"#include ".*\n                {
    // can put code to "store" include files here, or else switch to a 'FILE' state
    //BEGIN DEFINE;
}
"if"                            { ECHO; /*printf("        IF\n")                      */; return IF;}
"else"                          { ECHO; /*printf("        ELSE\n")                    */; return ELSE;}
"while"                         { ECHO; /*printf("        WHILE\n")                   */; return WHILE;}
"do"                            { ECHO; /*printf("        DO\n")                      */; return DO;}
"return"                        { ECHO; /*printf("        RETURN\n")                  */; return RETURN;}
"for"                           { ECHO; /*printf("        FOR\n")                     */; return FOR;}
"then"                          { ECHO; /*printf("        THEN\n")                    */; return THEN;}
"="                             { ECHO; /*printf("        ASSIGNMENT\n")              */; return ASSIGNMENT;}
"+"                             { ECHO; /*printf("        PLUS_OP\n")                 */; yylval.symbol = yytext[0]; return PLUS;}
"("                             { ECHO; /*printf("        L_PARENTHESIS\n")           */; return LEFTPARENS ;}
")"                             { ECHO; /*printf("        R_PARENTHESIS\n")           */; return RIGHTPARENS ;}
"-"                             { ECHO; /*printf("        MINUS_OP\n")                */; yylval.symbol = yytext[0]; return MINUS;}
"*"                             { ECHO; /*printf("        MULT_OP\n")                 */; yylval.symbol = yytext[0]; return MULTI;}
"/"                             { ECHO; /*printf("        DIV_OP\n")                  */; yylval.symbol = yytext[0]; return DIV;}
"%"                             { ECHO; /*printf("        MODULO_OP\n")               */; yylval.symbol = yytext[0]; return MODULO;}
"<<"                            { ECHO; /*printf("        LEFT_SHIFT\n")              */; yylval.symbol = yytext[0]; return SHIFTLEFT;}
">>"                            { ECHO; /*printf("        RIGHT_SHIFT\n")             */; yylval.symbol = yytext[0]; return SHIFTRIGHT;}
"=="                            { ECHO; /*printf("        COMPARISON_OP\n")           */;                                               }
"!="                            { ECHO; /*printf("        NOT_EQUAL\n")               */; yylval.value = atoi(yytext); return DIFF;}
"<"                             { ECHO; /*printf("        LESS_THAN\n")               */; yylval.value = atoi(yytext); return INF;}
">"                             { ECHO; /*printf("        GREATER_THAN\n")            */; yylval.value = atoi(yytext); return SUP;}
"<="                            { ECHO; /*printf("        LESS_THAN_OR_EQUAL\n")      */; yylval.value = atoi(yytext); return INFEQUAL;}
">="                            { ECHO; /*printf("        GREATER_THAN_OR_EQUAL\n")   */; yylval.value = atoi(yytext); return SUPEQUAL;}
"int"                           { ECHO; /*printf("        INT DECLARATION\n")         */; return INT;}
"string"                        { ECHO; /*printf("        STRING DECLARATION\n")      */; return STRING;}
"extern"                        { ECHO; /*printf("        EXTERN\n")                  */; return EXTERN;}
";"                             { ECHO; /*printf("        SEMICOLON\n")               */; yylval.symbol = yytext[0]; return ';';}
"{"                             { ECHO; /*printf("        LEFT_BRACE\n")              */; yylval.symbol = yytext[0]; return '{';}
"}"                             { ECHO; /*printf("        RIGHT_BRACE\n")             */; yylval.symbol = yytext[0]; return '}';}
","                             { ECHO; /*printf("        COMMA\n")                   */; yylval.symbol = yytext[0]; return ',';}
[0-9]+                          { ECHO; /*printf("        INTEGER\n")                 */; yylval.value = atoi(yytext); return INT;}
"\""[^"\""\n]*"\""              { ECHO; /*printf("        STRING_LITERAL\n")          */; yylval.str = strdup(yytext); return STRING;}
"\""[^"\""\n]*$                 { ECHO; /*printf("        * Unterminated String *\n") */;                                             }
"const int"                     { ECHO; /*printf("        CONST INT DECLARATION\n")   */; return CONST_INT;}
"const string"                  { ECHO; /*printf("        CONST STRING DECLARATION\n")*/; return CONST_STRING;}
"/*"                            { BEGIN COMMENT                                     ;}
<COMMENT>"*/"                   { BEGIN INITIAL                                     ;}
<COMMENT>([^*]|\n)+|.
<COMMENT><<EOF>>                {

    //ECHO;
    /*printf("* Unterminated Comment *\n")*/;
    yyterminate();

}
<DEFINE>"#define " { // probably redundant but not wanting to break code right now

    BEGIN MACRO;

}
[a-zA-Z_][a-zA-Z0-9_]* { // looks for IDENTIFIERS not sharing name with macro NAME

    //if(strncmp(yytext, var.c_str(),strlen(yytext))==0) {

        // ** this is sort of a hack, because without grammar, hard to resolve naming collisions... **
        // ** except it helps that I can rely on UPPERCASE macro naming convention
      //  main_buffer = YY_CURRENT_BUFFER;
       // expansion_buffer = yy_scan_string(biz.c_str()); // lex macro expansion and send to stdout
       // yy_switch_to_buffer(expansion_buffer);

   // }
    // this will create one superfluous IDENTIFIER, not sure how to rid of it, yet
    // also, it's late and I'm tired of guessing what i've missed that wasn't in the actual project descript
   // else ECHO; /*printf("        IDENTIFIER\n")*/ return IDENT;
   ECHO;
   //yylval.str = strdup(yytext);
   return IDENT;

}
<MACRO>[A-Z]+" " { // find macro NAME

    var = yytext; BEGIN ENDOFLINE;

}
<ENDOFLINE>.*\n { // store the rest in string variable

    biz = yytext; BEGIN INITIAL;

}
<<EOF>> {

    if (expansion_buffer)
    {
        // We were doing an expansion, return to where
        // we were.
        yy_switch_to_buffer(main_buffer);
        yy_delete_buffer(expansion_buffer);
        expansion_buffer = 0;
    }
    else
    yyterminate();
}
%%

仅使用lex文件输出样本。

   extern int bar( int baz );

int foo(int count)
{

    int sum;

    for (int 1 = 1; i <= count; i++)
        sum = sum + foo2(i);

    return sum;

}

int main(void) {


    string "car";
    printf("%d", IF);
    const string("Hello, World!");
    /* comments */
    if(1)
        return 1;
    return 0;


}

externToken: 263 (extern)
intToken: 258 (int)
barToken: 262 (bar)
(Token: 282 (()
intToken: 258 (int)
bazToken: 262 (baz)
)Token: 283 ())
;Token: 59 (;)
intToken: 258 (int)
fooToken: 262 (foo)
(Token: 282 (()
intToken: 258 (int)
countToken: 262 (count)
)Token: 283 ())
{Token: 123 ({)
intToken: 258 (int)
sumToken: 262 (sum)
;Token: 59 (;)
forToken: 269 (for)
(Token: 282 (()
intToken: 258 (int)
1Token: 258 (1)
=Token: 271 (=)
1Token: 258 (1)
;Token: 59 (;)
iToken: 262 (i)
<=Token: 275 (<=)
countToken: 262 (count)
;Token: 59 (;)
iToken: 262 (i)
+Token: 278 (+)
+Token: 278 (+)
)Token: 283 ())
sumToken: 262 (sum)
=Token: 271 (=)
sumToken: 262 (sum)
+Token: 278 (+)
foo2Token: 262 (foo2)
(Token: 282 (()
iToken: 262 (i)
)Token: 283 ())
;Token: 59 (;)
returnToken: 268 (return)
sumToken: 262 (sum)
;Token: 59 (;)
}Token: 125 (})
intToken: 258 (int)
mainToken: 262 (main)
(Token: 282 (()
voidToken: 262 (void)
)Token: 283 ())
{Token: 123 ({)
stringToken: 5 (string)
"car"Token: 5 ("car")
;Token: 59 (;)
printfToken: 262 (printf)
(Token: 282 (()
"%d"Token: 5 ("%d")
,Token: 44 (,)
IFToken: 262 (IF)
)Token: 283 ())
;Token: 59 (;)
const stringToken: 261 (const string)
(Token: 282 (()
"Hello, World!"Token: 5 ("Hello, World!")
)Token: 283 ())
;Token: 59 (;)
ifToken: 264 (if)
(Token: 282 (()
1Token: 258 (1)
)Token: 283 ())
returnToken: 268 (return)
1Token: 258 (1)
;Token: 59 (;)
returnToken: 268 (return)
0Token: 258 (0)
;Token: 59 (;)
}Token: 125 (})

要解析的上述程序的示例输出。

extern declare EXTERN
int INT type
bar(int INT type
baz PARAMETER
);int INT type
foo(int INT type
count PARAMETER
){int INT type
sum;for(intParse Error: 
syntax error, unexpected INT, expecting IDENT

有趣的是,如果我将语义动作添加到函数定义中,如下所示:

function-definition : {printf("print something");}
type function_declarator decl_glb_fct compound_instruction

然后我得到一个不同的解析器错误:

extern declare EXTERN
int INT type
bar(int INT type
baz declare PARAMETER
);int INT type
foo(int INT type
count declare PARAMETER
){Parse Error: 
*** syntax error, unexpected '{', expecting ';' or ',' ***

这是一种我不明白的行为。

0 个答案:

没有答案