我试图理解创建编译器的基本概念。 我尝试编写一个非常基本的c编译器,但遇到了一些问题。 当我尝试打印变量yylineno发生语法错误的地方时,我得到了一些行号错误。 有人知道为什么吗? 我已经在互联网上搜索了,但是我找不到一个明确的答案,谢谢。

comp.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);

}   

comp.y文件:

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.}

我得到:

错误:语法错误,意外的INT,期望';' 在第6行

错误:语法错误,意外的'}',应为';' 在第7行

#1楼 票数:1 已采纳

在C代码示例中,错误的行号正确。 没有遗失的要求; 在第2行int a行之后,而不是在第4行,第5行甚至第6行处为;int o

第6行的int o也丢失; 仅在第7行遇到}时才显示。

没有一个失踪; 要求与定义在同一行,因此不会报告可能出现的第一行号。 而是报告必须出现的最后一个行号。

粘贴到MSVC程序中的示例报告了相同的错误行号模式。

  ask by omn_1 translate from so

未解决问题?本站智能推荐:

1回复

函数声明的产生式规则中 yytext 中的意外值

我正在为大学作业编写一个带有 flex 和 bison 的编译器。 我在将函数标识符添加到我的符号表时遇到问题 - 在评估函数声明时,我在yytext中得到了我期望标识符的yytext括号。 在我的 flex 文件中, yylval是一个联合, vlex是一个struct : 在我的野牛文件中,
1回复

用 flex 和 bison 制作的编译器中的语法错误

首先,我对 flex 和 bison 很陌生,我似乎真的无法解决这个问题。 我已经创建了 flex 和 bison 文件,编译工作正常,这里是我的 flex 和 bison 文件 (ps 评论是法语) Flex: 和野牛: 这是我运行的命令来编译它们并执行编译器 test.mini
2回复

Bison Flex 编译器返回“y.tab.h”文件未找到错误

我正在尝试使用 Bison 和 Flex 构建一个句法分析器。 我有以下 .y / .l 文件: 圣比斯 SintLex.l: 我遵循的编译过程是:首先使用bison -d -o AnalizadorSintactico.c SintBis.y的 bison 文件,然后使用flex -o
1回复

野牛总是打印“语法错误”

好的。 所以我受命在我的编译器类中制作一个玩具编译器,因此我选择了Bison和Flex。 我已经掌握了有关Bison的大多数基础知识,并且在某种程度上知道LR,LALR和SLR解析器是如何工作的。 但是,这更多是一个技术问题。 在我的语法中,我已经开始添加带有error标记的错误产生。
1回复

使用此语法在flex / bison中获取语法错误

我正在尝试为编译器生成中间代码。 我在macOS上使用flex-bison。 当我尝试输入时,出现语法错误,并且我不知道该语法错误来自何处。 这是我的词法: 这是我的解析器 我尝试例如以下输入: 我得到这个错误 我试图放入printf来找出此语法错误的来
1回复

Flex Bison:Building C编译器-错误消息中的行号

当我尝试在yyerror函数中打印行号时,出现错误。 我正在使用OSX。 (compiler.l中的行号) compiler.c 我收到以下错误消息: 架构x86_64的未定义符号:“ _ lineNumber”,引用自:编译器中的_yyerror.o ld:架
1回复

Flex错误matchtype.h

我正在编写一个简单的flex程序,该程序需要一些输入并为解析器创建令牌。 我的代码[ex4.l] 此后,我运行了命令flex ex4.l ,该命令生成了lex.yy.c文件,当我尝试使用cc lex.yy.c -lfl运行该文件时,我陷入了此错误消息。 而且我一直收到此错误,我不
1回复

Flex和Bison代码 - 语法错误总是如此

首先,我需要说我对Flex和Bison很新,我有点困惑。 有一个学校项目要求我们使用Flex和Bison为某种CLIPS语言创建编译器。 我的代码有很多问题,但主要的是,无论我输入什么,我都会看到语法错误,而结果应该是其他东西。 理想的情况是完全适用于CLIPS语言。 EG当我写“4”时