代码之家  ›  专栏  ›  技术社区  ›  omn_1

yylineno为错误报告提供意外结果

  •  0
  • omn_1  · 技术社区  · 7 年前

    公司。l文件:

    %{
    #include <stdio.h>    
    #include <stdlib.h>
    #include <string.h>
    
    
    extern int yylineno;
    extern FILE* yyin;
    //extern char* yytext;
    void yyerror(char *s);
    
    
    %}
    
    
    %union {char* var;} 
    
    %token INT FLOAT CHAR DOUBLE VOID
    %token FOR WHILE 
    %token IF ELSE PRINTF 
    %token STRUCT 
    %token NUM 
    %token INCLUDE
    %token DOT
    %token <var> ID
    %right '='
    %left AND OR
    %left '<' '>' LE GE EQ NE LT GT
    %error-verbose
    
    %%
    
    start:  Function 
        | Declaration
        ;
    
    /* Declaration block */
    Declaration: Type Assignment ';' 
        | Assignment ';'    
        | FunctionCall ';'  
        | ArrayUsage ';'    
        | Type ArrayUsage ';'   
        | StructStmt ';'    
        | Arg ';'
        | error {yyerrok;}
        ;
    
    /* Assignment block */
    Assignment: ID '=' Assignment 
        | ID '=' FunctionCall   
        | ID '=' ArrayUsage     
        | ArrayUsage '=' Assignment
        | ID ',' Assignment   
        | NUM ',' Assignment
        | ID '+' Assignment    
        | ID '-' Assignment    
        | ID '*' Assignment     
        | ID '/' Assignment     
        | NUM '+' Assignment   
        | NUM '-' Assignment
        | NUM '*' Assignment
        | NUM '/' Assignment
        | '\'' Assignment '\''  
        | '(' Assignment ')'
        | '-' '(' Assignment ')'
        | '-' NUM
        | '-' ID  
        |   NUM
        |   ID  
        ;
    
    /* Function Call Block */
    FunctionCall : ID'('')'
        | ID'('Assignment')'
        ;
    
    /* Array Usage */
    ArrayUsage : ID'['Assignment']'  
        | ID'['error ']' {yyerrok;}
        ;
    
    /* Function block */
    Function: Type ID '(' ArgListOpt ')' CompoundStmt  
    
    ArgListOpt: ArgList
        |
        ;
    
    ArgList:  ArgList ',' Arg
        | Arg
        ;
    
    Arg:    Type ID
        ;
    
    CompoundStmt:   CompoundStmt '{' StmtList '}'
        |  '{' StmtList '}'
        | '{' StmtList {yyerror("Missing '}'"); YYERROR;}
        |  StmtList '}' {yyerror("Missing '{'"); YYERROR;}
        ;
    
    StmtList:   StmtList Stmt
        |
        ;
    
    Stmt: WhileStmt
        | Declaration
        | ForStmt
        | IfStmt
        | PrintFunc
        | ';'
        ;
    
    /* Type Identifier block */
    Type: INT 
        | FLOAT
        | CHAR
        | DOUBLE
        | VOID 
        ;
    
    /* Loop Blocks */ 
    WhileStmt: WHILE '(' Expr ')' Stmt  
        | WHILE '(' Expr ')' CompoundStmt 
        ;
    
    /* For Block */
    ForStmt: FOR '(' Expr ';' Expr ';' Expr ')' Stmt 
           | FOR '(' Expr ';' Expr ';' Expr ')' CompoundStmt 
           | FOR '(' Expr ')' Stmt 
           | FOR '(' Expr ')' CompoundStmt 
        ;
    
    /* IfStmt Block */
    IfStmt : IF '(' Expr ')' Stmt 
        ;
    
    /* Struct Statement */
    StructStmt : STRUCT ID '{' Type Assignment '}'  
        ;
    
    /* Print Function */
    PrintFunc : PRINTF '(' Expr ')' ';'
        ;
    
    /*Expression Block*/
    Expr:   
        | Expr LE Expr 
        | Expr GE Expr
        | Expr NE Expr
        | Expr EQ Expr
        | Expr GT Expr
        | Expr LT Expr
        | Assignment
        | ArrayUsage
        ;
    
    %%
    
    int count = 0;
    
    
    
    
    
    
    
    int main() {
    
        int i;
    
        for(i=0; i<100; i++) {
    
            variables[i] = " ";
    
         }
    
        yyin = stdin;
    
        do { 
    
            yyparse();
    
        } while(!feof(yyin));
    
        return 0;
    }
    
    
    
    
    
    void yyerror(char* s) {
    
    
    
    
        printf("Error : %s  at line %d \n", s, yylineno);
    
    }   
    

    alpha [a-zA-Z]
    digit [0-9]
    
    %{
    #include "y.tab.h"
    #include <stdio.h>
    
    int line_n = 1;
    
    %}
    
    %option  nodefault yylineno
    
    
    
    %%
    
    
    [\t\n]+                      {;}
    "int"                        {return INT;}
    "float"                      {return FLOAT;}
    "char"                       { return CHAR;}
    "void"                       {return VOID;}
    "double"                     {return DOUBLE;}
    "for"                        {return FOR;}
    "while"                      {return WHILE;}
    "if"                         {return IF;}
    "else"                       {return ELSE;}
    "printf"                     {return PRINTF;}
    "struct"                     {return STRUCT;}
    ^"#include ".+               {;}
    {digit}+                     {return NUM;}
    {alpha}({alpha}|{digit})*    {yylval.var = strdup(yytext);return ID;}
    "<="                         {return LE;}
    ">="                         {return GE;}
    "=="                         {return EQ;}
    "!="                         {return NE;}
    ">"                          {return GT;}
    "<"                          {return LT;}
    "."                          {return DOT;}
    \/\/.*                       {;}
    \/\*(.*\n)*.*\*\/            {;}
    [ \t\r\n]+                   {;}
    .                            {return *yytext;}
    
    
    %%
    
    
    
    int yywrap (void) {return 1;}
    

    例如,当我尝试检查以下代码时:

    1.int main(){
    2.   int a
    3.
    4. 
    5. 
    6.   int o 
    7.}
    

    我得到:

    错误:语法错误,意外的“}”,应为“;”在7号线

    1 回复  |  直到 7 年前
        1
  •  1
  •   Weather Vane    7 年前

    在C代码示例中,错误的行号是正确的。对于缺失项没有要求 ; 之后 int a ;int o .

    int o 第6行也有一个 ; } 在7号线上遇到。

    两个人都不见了 ; 可以 目前尚未报道。而不是它所在的最后一个行号 必须 有报道称。