首页 > 解决方案 > 为什么 yyerror() 被调用两次?

问题描述

我是使用 C 语言编译器的新手,但是我遇到了错误,我不知道它来自哪里。

我认为编译器的 Lex 部分没有问题。所有语法规则都正确打印,但我仍然打印两次语法错误:

为什么在最后两行我在结果文件中得到这个:

yyerror :syntax error
yyerror :syntax error

这是我想从语法上分析的新文档:

Program Test_2;

Variables
    GlobalReal : Real;
    GlobalInt  : Integer;
    GlobalString : String;
    GlobalIntVector : Integer[250];
    GlobalIntMatrix : Integer[256, 256];    
EndVars

Procedures

    Procedure FooDummyProc();
    
    NoVariables
    EndVars
    
    NoProcedures
    EndProcs
    
    Begin
    ;
    End;

    Procedure FooProcess_1(fooPar1 : Integer);
    
    Variables 
        LoopIndex : Integer;
        ProcMsg   : String; 
    EndVars
    
    NoProcedures
    EndProcs
    
    Begin 
        For LoopIndex := 1 to fooPar Do     
            Write("Im executing the ith Iteration");
        
        Write("I'm Done!!!!")
    
    End;
    
    
    Procedure FooAssign(fooPar2 : Real);
    
    Variables
        FooValue : Real;
    EndVars
    
    NoProcedures
    EndProcs
    
    Begin 
        FooValue := fooPar2;
        GlobalIntVector[FooValue] := 4;
        A := A/(FooValue + fooPar2) * 2;
        B := GlobalIntMatrix[FooValue, FooValue]        
    End;
    
    Procedure FooConditional(fooPar3 : String);
    
    Variables
        FooValue : Integer;
    EndVars
    
    NoProcedures
    EndProcs
    
    Begin
        If A = FooValue Then 
            Write("The condition is true")
        Else 
            Read (FooValue);
            
        If B = 2 Then
            Write ("This branch is also true")
        Else
            If B > 2 Then 
                Read(B)
            Else
                Read(C);
        
        If B <> 3 Then 
            Write("This is the last comparison")
        Else 
            Write(C);
        
        If C = 4 Then 
            C := 3.456
        Else        
            D := 3.8787;
        
        C := 2*Foo(34,15)
        
    
    End 
    

EndProcs;

{ No main Begin-End block }

这是我的解析器

%{
    #include <stdio.h>
    
    int yylex();
    int yyerror(char *s);

%}


%token  _LBRACK 1
%token  _RBRACK 2
%token  _LPAREN 3
%token  _RPAREN 4
%token  _SEMI 5
%token  _COLON 6
%token  _COMMA 7
%token  _ASSIGN 8
%token  _PLUS 9
%token  _MINUS 10
%token  _MULT 11
%token  _DIVIDE 12
%token  _EQL 13
%token  _LESS 14
%token  _GTR 15
%token  _LEQ 16
%token  _GEQ 17
%token  _NEQ 18
%token _BEGIN 30
%token _PROGRAM 19
%token _ENDVARS 20
%token _ENDPROCS 21
%token _VARS 22
%token _NOVARS 23
%token _INTEGER 24
%token _REAL 25
%token _STRING 26
%token _PROCS 27
%token _NOPROCS 28
%token _PROC 29
%token _END 31
%token _FOR 32
%token _TO 33
%token _DO 34
%token _IF 35
%token _THEN 36
%token _ELSE 37
%token _READ 38
%token _WRITE 39
%token _ID 40
%token _ECONST 41
%token _ICONST 42
%token _RCONST 43
%token _LITERAL 44
%token _COMEN 45

%start program

%%

    program:
        title _SEMI block   {printf("Rule in program: _SEMI \n");}
    ;

    title:
        _PROGRAM _ID    {printf("Rule in title: _PROGRAM _ID \n");}
    ;

    block:
        vars _ENDVARS procs _ENDPROCS code  {printf("Rule in title: _PROGRAM _ID \n");}
    ;

    vars:
        _VARS varlist _SEMI     {printf("Rule in vars: _VARS varlist _SEMI \n");}
        | _NOVARS   {printf("Rule in vars: _NOVARS");}
    ;

    varlist:
        varlist _SEMI vardef    {printf("Rule in varlist: varlist _SEMI vardef \n");}
        | vardef    {printf("Rule in varlist: _vardef");}
    ;

    bnl:
        _LBRACK nlist _RBRACK   {printf("Rule in bnl: _LBRACK nlist _RBRACK \n");}
    ;

    vardef:
        _ID _COLON _INTEGER     {printf("Rule in vardef: _ID _COLON _INTEGER \n");} 
        | _ID _COLON _REAL      {printf("Rule in vardef: _ID _COLON _REAL \n");}
        | _ID _COLON _INTEGER bnl   {printf("Rule in vardef: _ID _COLON _INTEGER bnl \n");}
        | _ID _COLON _STRING    {printf("Rule in vardef: _ID _COLON _STRING \n");}
    ;
    
    nlist:
        nlist _COMMA _ICONST    {printf("Rule in nlist: nlist _COMMA _ICONST \n");}
        | _ICONST       {printf("Rule in nlist: _ICONST \n");}
    ;

    procs:
        _PROCS proclist     {printf("Rule in procs: _PROCS proclist \n ");}
        | _NOPROCS          {printf("Rule in procs: _NOPROCS \n");}
    ;

    proclist:
        proclist _SEMI procdef      {printf("Rule in proclist: proclist _SEMI procdef \n");}
        | procdef       {printf("Rule in proclist: procdef \n");}
    ;

    procdef:
        ptitle _SEMI block  {printf("Rule in procdef: ptitle _SEMI block \n");}
    ;

    ptitle:
        _PROC _ID _LPAREN varlist _RPAREN   {printf("Rule in ptitle: _PROC _ID _LPAREN varlist _RPAREN \n");}
        | _PROC _ID _LPAREN _RPAREN         {printf("Rule in ptitle: _PROC _ID _LPAREN _RPAREN \n");}
    ;

    code:
        _BEGIN para _END {printf("Rule in code: _BEGIN para _END \n");}
        | _SEMI         {printf("Rule in code:  _SEMI \n");}
    ;

    para:
        para _SEMI stmt     {printf("Rule in para: para _SEMI stmt \n");}
        | stmt              {printf("Rule in para: stmt \n");}
    ;

    stmt:
        assign      {printf("Rule in stmt: assign \n");}
        | cond      {printf("Rule in stmt: cond \n");}
        | loop      {printf("Rule in stmt: loop \n");}
        | input     {printf("Rule in stmt: input \n");}
        | output    {printf("Rule in stmt: output \n");}
        | code      {printf("Rule in stmt: code \n");}
    ;

    assign:
         ids _ASSIGN expr   {printf("Rule in assign: ids _ASSIGN expr \n");}
    ;

    expr:
        expr _PLUS term     {printf("Rule in expr: expr _PLUS term \n");}
        | expr _MINUS term  {printf("Rule in expr: expr _MINUS term \n");}
        | term  {printf("Rule in expr: term \n");}
    ;

    ids:
        _ID {printf("Rule in ids: _ID \n");}
        | _ID _LBRACK vallist _RBRACK   {printf("Rule in ids: _ID _LBRACK vallist _RBRACK \n");}
    ;

    term:
        term _MULT fac      {printf("Rule in term: term _MULT fac  \n");}
        | term _DIVIDE fac  {printf("Rule in term: term _DIVIDE fac \n");}
        | fac   {printf("Rule in term: fac \n");}
    ;

    vallist:
        vallist _COMMA it   {printf("Rule in vallist: vallist _COMMA it  \n");}
        | it    {printf("Rule in vallist: it \n");}
    ;

    fac:
        val     {printf("Rule in fac: val \n");}
        | _LPAREN expr _RPAREN      {printf("Rule in fac: _LPAREN expr _RPAREN \n");}
    ;

    val:
        ids     {printf("Rule in val: ids \n");}
        | _ID _LPAREN vallist _RPAREN   {printf("Rule in val: _ID _LPAREN vallist _RPAREN\n");}
        | _ICONST   {printf("Rule in val: _ICONST \n");}    
        | _RCONST   {printf("Rule in val: _RCONST \n");}
        | _ECONST   {printf("Rule in val: _ECONST \n");}
        | _LITERAL  {printf("Rule in val: _LITERAL \n");}
    ;


    it:
        _ID {printf("Rule in it: _ID \n");}
        | _ICONST   {printf("Rule in it: _ICONST \n");}
    ;

    cond: 
        _IF expr bop expr _THEN stmt _ELSE stmt     {printf("Rule in cond: _IF expr bop expr _THEN stmt _ELSE stmt \n");}
    ;

    bop:
        _EQL {printf("Rule in bop: _EQL \n");}
        | _LESS {printf("Rule in bop: _LESS \n");}
        | _GTR  {printf("Rule in bop: _GTR \n");}
        | _LEQ  {printf("Rule in bop: _LEQ \n");}
        | _GEQ  {printf("Rule in bop: _GEQ \n");}
        | _NEQ  {printf("Rule in bop: _NEQ \n");}
    ;
        
    loop:   
        _FOR assign _TO expr _DO stmt   {printf("Rule in loop: _FOR assign _TO expr _DO stmt \n");}
    ;
    
    input:
        _READ _LPAREN _ID _RPAREN   {printf("Rule in input: _READ _LPAREN _ID _RPAREN \n");}
    ;

    output:
        _WRITE _LPAREN _ID _RPAREN      {printf("Rule in output: _WRITE _LPAREN _ID _RPAREN \n");}
        | _WRITE _LPAREN _LITERAL _RPAREN   {printf("Rule in output: _WRITE _LPAREN _LITERAL _RPAREN \n");}
    ;


%%


int yyerror(char *s)
{
    printf ("yyerror :%s\n", s);
    return (0);
}

这是我的scanner.l

%option noyywrap

D [0-9]
A [a-zA-Z]

%{
#include "Tokens.h"

#include "lex.yy.x"

int tokenCount;
%}

%%
"["                         {tokenCount++; return (_LBRACK);}
"]"                         {tokenCount++; return (_RBRACK);}
"("                         {tokenCount++; return (_LPAREN);}
")"                         {tokenCount++; return (_RPAREN);}
";"                         {tokenCount++; return (_SEMI);}
":"                         {tokenCount++; return (_COLON);}
","                         {tokenCount++; return (_COMMA);}
":="                            {tokenCount++; return (_ASSIGN);}
"+"                         {tokenCount++; return (_PLUS);}
"-"                         {tokenCount++; return (_MINUS);}
"*"                         {tokenCount++; return (_MULT);}
"/"                         {tokenCount++; return (_DIVIDE);}
"="                         {tokenCount++; return (_EQL);}
"<"                         {tokenCount++; return (_LESS);}
">"                         {tokenCount++; return (_GTR);}
"<="                            {tokenCount++; return (_LEQ);}
">="                            {tokenCount++; return (_GEQ);}
"<>"                            {tokenCount++; return (_NEQ);}
[Pp][Rr][Oo][Gg][Rr][Aa][Mm]                {tokenCount++; return (_PROGRAM);}
[Ee][Nn][Dd][Vv][Aa][Rr][Ss]                {tokenCount++; return (_ENDVARS);}
[Ee][Nn][Dd][Pp][Rr][Oo][Cs][Ss]            {tokenCount++; return (_ENDPROCS);}
[Vv][Aa][Rr][Ii][Aa][Bb][Ll][Ee][Ss]            {tokenCount++; return (_VARS);}
[Nn][Oo][Vv][Aa][Rr][Ii][Aa][Bb][Ll][Ee][Ss]        {tokenCount++; return (_NOVARS);}
[Ii][Nn][Tt][Ee][Gg][Ee][Rr]                {tokenCount++; return (_INTEGER);}
[Rr][Ee][Aa][Ll]                    {tokenCount++; return (_REAL);}
[Ss][Tt][Rr][Ii][Nn][Gg]                {tokenCount++; return (_STRING);}
[Pp][Rr][Oo][Cc][Ee][Dd][Uu][Rr][Ee][Ss]        {tokenCount++; return (_PROCS);}
[Nn][Oo][Pp][Rr][Oo][Cc][Ee][Dd][Uu][Rr][Ee][Ss]    {tokenCount++; return (_NOPROCS);}
[Pp][Rr][Oo][Cc][Ee][Dd][Uu][Rr][Ee]            {tokenCount++; return (_PROC);}
[Bb][Ee][Gg][Ii][Nn]                    {tokenCount++; return (_BEGIN);}
[Ee][Nn][Dd]                        {tokenCount++; return (_END);}
[Ff][Oo][Rr]                        {tokenCount++; return (_FOR);}
[Tt][Oo]                        {tokenCount++; return (_TO);}
[Dd][Oo]                        {tokenCount++; return (_DO);}
[Ii][Ff]                        {tokenCount++; return (_IF);}
[Tt][Hh][Ee][Nn]                    {tokenCount++; return (_THEN);}
[Ee][Ll][Ss][Ee]                    {tokenCount++; return (_ELSE);}
[Rr][Ee][Aa][Dd]                    {tokenCount++; return (_READ);}
[Ww][Rr][Ii][Tt][Ee]                    {tokenCount++; return (_WRITE);}
[a-zA-Z0-9\-?\_?]+                  {tokenCount++; return (_ID);}
([+-]?[0-9]*\.[0-9]+[eE][\+-]?[0-9]+)|([+-]?[0-9]+[eE][\+-]?[0-9]+) {tokenCount++; return (_ECONST);}
[\+-]?[0-9]+                        {tokenCount++; return (_ICONST);}
[\+-]?[0-9]*.[0-9]+                 {tokenCount++; return (_RCONST);}
\{'.*'\}|\{".*"\}                   {tokenCount++; return (_LITERAL);}
\{.*\}                          {tokenCount++; return (_COMEN);}
\{[a-zA-Z0-9~!@#$%^&*()_+|":?><.,';\-\/*\ ]+        {tokenCount++; return (_ERROR1);}
\"[a-zA-Z0-9~!@#$%^&*()_+|:?><.,';\-\/*{}\ ]+       {tokenCount++; return (_ERROR2);}
.

%%

void yyerror(int tokenCount)
{
    printf("Hubo un error al analizar el lexema %s en la columna %d", yytext, tokenCount);
    exit(1);
}

void yytrap() {}

这是我的输出:

Rule in title: _PROGRAM _ID 
Rule in vardef: _ID _COLON _REAL 
Rule in varlist: vardefRule in vardef: _ID _COLON _INTEGER 
Rule in varlist: varlist _SEMI vardef 
Rule in vardef: _ID _COLON _STRING 
Rule in varlist: varlist _SEMI vardef 
Rule in nlist: _ICONST 
Rule in bnl: _LBRACK nlist _RBRACK 
Rule in vardef: _ID _COLON _INTEGER bnl 
Rule in varlist: varlist _SEMI vardef 
Rule in nlist: _ICONST 
Rule in nlist: nlist _COMMA _ICONST 
Rule in bnl: _LBRACK nlist _RBRACK 
Rule in vardef: _ID _COLON _INTEGER bnl 
Rule in varlist: varlist _SEMI vardef 
Rule in vars: _VARS varlist _SEMI 
Rule in ptitle: _PROC _ID _LPAREN _RPAREN 
Rule in vars: _NOVARSRule in procs: _NOPROCS 
Rule in code:  _SEMI 
Rule in stmt: code 
Rule in para: stmt 
Rule in code: _BEGIN para _END 
Rule in block: _PROGRAM _ID 
Rule in procdef: ptitle _SEMI block 
Rule in proclist: procdef 
Rule in vardef: _ID _COLON _INTEGER 
Rule in varlist: vardefRule in ptitle: _PROC _ID _LPAREN varlist _RPAREN 
Rule in vardef: _ID _COLON _INTEGER 
Rule in varlist: vardefRule in vardef: _ID _COLON _STRING 
Rule in varlist: varlist _SEMI vardef 
Rule in vars: _VARS varlist _SEMI 
Rule in procs: _NOPROCS 
Rule in ids: _ID 
Rule in val: _ICONST 
Rule in fac: val 
Rule in term: fac 
Rule in expr: term 
Rule in assign: ids _ASSIGN expr 
Rule in ids: _ID 
Rule in val: ids 
Rule in fac: val 
Rule in term: fac 
Rule in expr: term 
Rule in output: _WRITE _LPAREN _LITERAL _RPAREN 
Rule in stmt: output 
Rule in loop: _FOR assign _TO expr _DO stmt 
Rule in stmt: loop 
Rule in para: stmt 
Rule in output: _WRITE _LPAREN _LITERAL _RPAREN 
Rule in stmt: output 
Rule in para: para _SEMI stmt 
Rule in code: _BEGIN para _END 
Rule in block: _PROGRAM _ID 
Rule in procdef: ptitle _SEMI block 
Rule in proclist: proclist _SEMI procdef 
Rule in vardef: _ID _COLON _REAL 
Rule in varlist: vardefRule in ptitle: _PROC _ID _LPAREN varlist _RPAREN 
Rule in vardef: _ID _COLON _REAL 
Rule in varlist: vardefRule in vars: _VARS varlist _SEMI 
Rule in procs: _NOPROCS 
Rule in ids: _ID 
Rule in ids: _ID 
Rule in val: ids 
Rule in fac: val 
Rule in term: fac 
Rule in expr: term 
Rule in assign: ids _ASSIGN expr 
Rule in stmt: assign 
Rule in para: stmt 
Rule in it: _ID 
Rule in vallist: it 
Rule in ids: _ID _LBRACK vallist _RBRACK 
Rule in val: _ICONST 
Rule in fac: val 
Rule in term: fac 
Rule in expr: term 
Rule in assign: ids _ASSIGN expr 
Rule in stmt: assign 
Rule in para: para _SEMI stmt 
Rule in ids: _ID 
Rule in ids: _ID 
Rule in val: ids 
Rule in fac: val 
Rule in term: fac 
Rule in ids: _ID 
Rule in val: ids 
Rule in fac: val 
Rule in term: fac 
Rule in expr: term 
Rule in ids: _ID 
Rule in val: ids 
Rule in fac: val 
Rule in term: fac 
Rule in expr: expr _PLUS term 
Rule in fac: _LPAREN expr _RPAREN 
Rule in term: term _DIVIDE fac 
Rule in val: _ICONST 
Rule in fac: val 
Rule in term: term _MULT fac  
Rule in expr: term 
Rule in assign: ids _ASSIGN expr 
Rule in stmt: assign 
Rule in para: para _SEMI stmt 
Rule in ids: _ID 
Rule in it: _ID 
Rule in vallist: it 
Rule in it: _ID 
Rule in vallist: vallist _COMMA it  
Rule in ids: _ID _LBRACK vallist _RBRACK 
Rule in val: ids 
Rule in fac: val 
Rule in term: fac 
Rule in expr: term 
Rule in assign: ids _ASSIGN expr 
Rule in stmt: assign 
Rule in para: para _SEMI stmt 
Rule in code: _BEGIN para _END 
Rule in block: _PROGRAM _ID 
Rule in procdef: ptitle _SEMI block 
Rule in proclist: proclist _SEMI procdef 
Rule in vardef: _ID _COLON _STRING 
Rule in varlist: vardefRule in ptitle: _PROC _ID _LPAREN varlist _RPAREN 
Rule in vardef: _ID _COLON _INTEGER 
Rule in varlist: vardefRule in vars: _VARS varlist _SEMI 
Rule in procs: _NOPROCS 
Rule in ids: _ID 
Rule in val: ids 
Rule in fac: val 
Rule in term: fac 
Rule in expr: term 
Rule in bop: _EQL 
Rule in ids: _ID 
Rule in val: ids 
Rule in fac: val 
Rule in term: fac 
Rule in expr: term 
Rule in output: _WRITE _LPAREN _LITERAL _RPAREN 
Rule in stmt: output 
Rule in input: _READ _LPAREN _ID _RPAREN 
Rule in stmt: input 
Rule in cond: _IF expr bop expr _THEN stmt _ELSE stmt 
Rule in stmt: cond 
Rule in para: stmt 
Rule in ids: _ID 
Rule in val: ids 
Rule in fac: val 
Rule in term: fac 
Rule in expr: term 
Rule in bop: _EQL 
Rule in val: _ICONST 
Rule in fac: val 
Rule in term: fac 
Rule in expr: term 
Rule in output: _WRITE _LPAREN _LITERAL _RPAREN 
Rule in stmt: output 
Rule in ids: _ID 
Rule in val: ids 
Rule in fac: val 
Rule in term: fac 
Rule in expr: term 
Rule in bop: _GTR 
Rule in val: _ICONST 
Rule in fac: val 
Rule in term: fac 
Rule in expr: term 
Rule in input: _READ _LPAREN _ID _RPAREN 
Rule in stmt: input 
Rule in input: _READ _LPAREN _ID _RPAREN 
Rule in stmt: input 
Rule in cond: _IF expr bop expr _THEN stmt _ELSE stmt 
Rule in stmt: cond 
Rule in cond: _IF expr bop expr _THEN stmt _ELSE stmt 
Rule in stmt: cond 
Rule in para: para _SEMI stmt 
Rule in ids: _ID 
Rule in val: ids 
Rule in fac: val 
Rule in term: fac 
Rule in expr: term 
Rule in bop: _NEQ 
Rule in val: _ICONST 
Rule in fac: val 
Rule in term: fac 
Rule in expr: term 
Rule in output: _WRITE _LPAREN _LITERAL _RPAREN 
Rule in stmt: output 
Rule in output: _WRITE _LPAREN _ID _RPAREN 
Rule in stmt: output 
Rule in cond: _IF expr bop expr _THEN stmt _ELSE stmt 
Rule in stmt: cond 
Rule in para: para _SEMI stmt 
Rule in ids: _ID 
Rule in val: ids 
Rule in fac: val 
Rule in term: fac 
Rule in expr: term 
Rule in bop: _EQL 
Rule in val: _ICONST 
Rule in fac: val 
Rule in term: fac 
Rule in expr: term 
Rule in ids: _ID 
Rule in val: _RCONST 
Rule in fac: val 
Rule in term: fac 
Rule in expr: term 
Rule in assign: ids _ASSIGN expr 
Rule in stmt: assign 
Rule in ids: _ID 
Rule in val: _RCONST 
Rule in fac: val 
Rule in term: fac 
Rule in expr: term 
Rule in assign: ids _ASSIGN expr 
Rule in stmt: assign 
Rule in cond: _IF expr bop expr _THEN stmt _ELSE stmt 
Rule in stmt: cond 
Rule in para: para _SEMI stmt 
Rule in ids: _ID 
Rule in val: _ICONST 
Rule in fac: val 
Rule in term: fac 
Rule in it: _ICONST 
Rule in vallist: it 
Rule in it: _ICONST 
Rule in vallist: vallist _COMMA it  
Rule in val: _ID _LPAREN vallist _RPAREN
Rule in fac: val 
Rule in term: term _MULT fac  
Rule in expr: term 
Rule in assign: ids _ASSIGN expr 
Rule in stmt: assign 
Rule in para: para _SEMI stmt 
Rule in code: _BEGIN para _END 
Rule in block: _PROGRAM _ID 
Rule in procdef: ptitle _SEMI block 
Rule in proclist: proclist _SEMI procdef 
Rule in procs: _PROCS proclist 
 Rule in code:  _SEMI 
Rule in block: _PROGRAM _ID 
Rule in program: _SEMI 
yyerror :syntax error
yyerror :syntax error

标签: ccompiler-errorscompiler-constructionbisonflex-lexer

解决方案


推荐阅读