首页 > 解决方案 > Flex & Bison:“真”被解释为和 ID

问题描述

我正在 Ubuntu OS 中编写解析器和扫描器。在我的弹性代码“scanner.l”中,我有一个 IDENTIFIER 令牌和 BOOL_LITERAL 令牌。IDENTIFIER 是任何单词,BOOL_LITERAL 是真或假。在我的野牛代码“parser.y”中,我有一个语法,它应该能够通过初级生产获取 BOO_LITERAL。

但是,代码没有按预期工作。这是错误

这是我所有的文件:

扫描仪.l

%{
#include <string>
#include <vector>

using namespace std;

#include "listing.h"
#include "tokens.h"

%}

%option noyywrap

ws [ \t\r]+
comment (\-\-.*\n)|\/\/.*\n
line [\n]
digit [0-9]
int {digit}+
real     {int}"."{int}([eE][+-]?{digit})?
boolean   ["true""false"]
punc [\(\),:;]
addop ["+""-"]
mulop ["*""\/"]
relop     [="/=">">=""<="<]
id [A-Za-z][A-Za-z0-9]*
%%

{ws} { ECHO; }
{comment} { ECHO; nextLine();}
{line} { ECHO; nextLine();}
{relop} { ECHO; return(RELOP); }
{addop} { ECHO; return(ADDOP); }
{mulop} { ECHO; return(MULOP); }
begin { ECHO; return(BEGIN_); }
boolean { ECHO; return(BOOLEAN); }
end { ECHO; return(END); }
endreduce { ECHO; return(ENDREDUCE); }
function { ECHO; return(FUNCTION); }
integer { ECHO; return(INTEGER); }
real { ECHO; return(REAL); }
is { ECHO; return(IS); }
reduce { ECHO; return (REDUCE); }
returns { ECHO; return(RETURNS); }
and { ECHO; return(ANDOP); }
{boolean} { ECHO; return(BOOL_LITERAL); }
{id} { ECHO; return(IDENTIFIER);}
{int} { ECHO; return(INT_LITERAL); }
{real} { ECHO; return(REAL_LITERAL); }
{punc} { ECHO; return(yytext[0]); }
. { ECHO; appendError(LEXICAL, yytext); }

%%

解析器.y

%{

#include <string>

using namespace std;

#include "listing.h"

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

%}

%error-verbose

%token INT_LITERAL REAL_LITERAL BOOL_LITERAL
%token IDENTIFIER

%token ADDOP MULOP RELOP ANDOP

%token BEGIN_ BOOLEAN END ENDREDUCE FUNCTION INTEGER IS REDUCE RETURNS REAL

%%

function:
function_header optional_variable body ;

function_header:
FUNCTION IDENTIFIER RETURNS type ';' ;

parameters:
parameters ',' |
parameter ;

parameter:
IDENTIFIER ':' type |
;

optional_variable:
variable |
;

variable:
IDENTIFIER ':' type IS statement_ ;

type:
INTEGER |
BOOLEAN |
REAL ;

body:
BEGIN_ statement_ END ';' ;
   
statement_:
statement ';' |
error ';' ;

statement:
expression |
REDUCE operator reductions ENDREDUCE ;

operator:
ADDOP |
MULOP ;

reductions:
reductions statement_ |
;
   
expression:
expression ANDOP relation |
relation ;

relation:
relation RELOP term |
term;

term:
term ADDOP factor |
factor ;
     
factor:
factor MULOP primary |
primary ;

primary:
'(' expression ')' |
INT_LITERAL |
REAL_LITERAL |
BOOL_LITERAL |
IDENTIFIER ;
   
%%

void yyerror(const char* message)
{
appendError(SYNTAX, message);
}

int main(int argc, char *argv[])    
{
firstLine();
yyparse();
lastLine();
return 0;
}

Other associated files:

清单.h

enum ErrorCategories {LEXICAL, SYNTAX, GENERAL_SEMANTIC, DUPLICATE_IDENTIFIER,
    UNDECLARED};

void firstLine();
void nextLine();
int lastLine();
void appendError(ErrorCategories errorCategory, string message);

清单.cc

#include <cstdio>
#include <string>

using namespace std;

#include "listing.h"

static int lineNumber;
static string error = "";
static int totalErrors = 0;

static void displayErrors();

void firstLine()
{
    lineNumber = 1;
    printf("\n%4d  ",lineNumber);
}

void nextLine()
{
    displayErrors();
    lineNumber++;
    printf("%4d  ",lineNumber);
}

int lastLine()
{
    printf("\r");
    displayErrors();
    printf("     \n");
    return totalErrors;
}
    
void appendError(ErrorCategories errorCategory, string message)
{
    string messages[] = { "Lexical Error, Invalid Character ", "",
        "Semantic Error, ", "Semantic Error, Duplicate Identifier: ",
        "Semantic Error, Undeclared " };

    error = messages[errorCategory] + message;
    totalErrors++;
}

void displayErrors()
{
    if (error != "")
        printf("%s\n", error.c_str());
    error = "";
}

马克勒

compile: scanner.o parser.o listing.o
    g++ -o compile scanner.o parser.o listing.o
    
scanner.o: scanner.c listing.h tokens.h
    g++ -c scanner.c

scanner.c: scanner.l
    flex scanner.l
    mv lex.yy.c scanner.c

parser.o: parser.c listing.h 
    g++ -c parser.c

parser.c tokens.h: parser.y
    bison -d -v parser.y
    mv parser.tab.c parser.c
    mv parser.tab.h tokens.h

listing.o: listing.cc listing.h
    g++ -c listing.cc

注意: 我必须再次运行“makeile”、“bison -d parser.y”,最后再次运行“makefile”。然后,我运行以下命令“./compile < incremental1.txt”,我收到以下错误: 在此处输入图像描述

请帮助我理解为什么会出现语法错误。

标签: clinuxubuntubisonlex

解决方案


你的布尔模式应该是“true”|“false”而不是[“true”“false”]。

老实说,你的模式设置方式很奇怪。有什么理由不使用:

...
%%
"true" { /* */ return BOOL_LITERAL; }
"false { /* */ return BOOL_LITERAL; }

当您不尝试匹配文字时,模式是有意义的,但在这里。


推荐阅读