4

考虑这个 lex.l 文件:

%{
#include "y.tab.h"
%}

digit         [0-9]
letter        [a-zA-Z]

%%
"+"                  { return PLUS;       }
"-"                  { return MINUS;      }
"*"                  { return TIMES;      }
"/"                  { return SLASH;      }
"("                  { return LPAREN;     }
")"                  { return RPAREN;     }
";"                  { return SEMICOLON;  }
","                  { return COMMA;      }
"."                  { return PERIOD;     }
":="                 { return BECOMES;    }
"="                  { return EQL;        }
"<>"                 { return NEQ;        }
"<"                  { return LSS;        }
">"                  { return GTR;        }
"<="                 { return LEQ;        }
">="                 { return GEQ;        }
"begin"              { return BEGINSYM;   }
"call"               { return CALLSYM;    }
"const"              { return CONSTSYM;   }
"do"                 { return DOSYM;      }
"end"                { return ENDSYM;     }
"if"                 { return IFSYM;      }
"odd"                { return ODDSYM;     }
"procedure"          { return PROCSYM;    }
"then"               { return THENSYM;    }
"var"                { return VARSYM;     }
"while"              { return WHILESYM;   }
{letter}({letter}|{digit})* {
                       yylval.id = strdup(yytext);
                       return IDENT;      }
{digit}+             { yylval.num = atoi(yytext);
                       return NUMBER;     }
[ \t\n\r]            /* skip whitespace */
.                    { printf("Unknown character [%c]\n",yytext[0]);
                       return UNKNOWN;    }
%%

int yywrap(void){return 1;}

在这个例子中,标识符不能是保留字,因为它会在上面匹配。在这种情况下,是否有某种技术允许将标识符定义为保留字?

4

1 回答 1

5

我认为您正在寻找的是一种让解析器告诉词法分析器在给定上下文中保留哪些单词的方法。然而,这并不容易,特别是因为解析器经常在任何操作发生之前读取前瞻标记。

一个更简单的解决方案是yylval为任何半保留字适当地设置,然后在你的解析器中使用这样的产生式:

id_or_procedure: IDENTIFIER | PROCSYM;

id_or_conditional: IDENTIFIER | THENSYM | ODDSYM;

这并不容易维护,因为它需要您弄清楚哪些半保留词适用于哪些上下文。但是如果你只有几个半保留字,而且它们只在一些非常特定的上下文中保留,那么它是相当可行的。

于 2013-11-04T14:39:47.640 回答