正如吉姆所说,使用你的词汇工具来处理这些情况,而不是把它们写进你的语法产生中。
例如,我通常使用 Flex 进行词法分析,使用 Bison 来定义我的语法(可能就像你所做的那样)。
您可以通过以下方式实现您想要的结果(这只是一个示例,因此非常简单,不能做太多事情):
词法分析器.l
/* lexicalAnalyzer.l
Specifications of tokens for some language.
*/
%{
%}
/*
* Definitions of regular expressions
* Note: You capture whitespace here...
*/
WSPACE [ \t\r]+ //We take care of the spaces here...
/*
* Tokens
*/
%%
"=" {
printf("TOKEN: EQ LEXEME: %s\n", yytext);
return T_EQ;
}
"(" {
printf("TOKEN: OBRCKT LEXEME: %s\n", yytext);
return T_OBRCKT;
}
")" {
printf("TOKEN: CBRCKT LEXEME: %s\n", yytext);
return T_CBRCKT;
}
"<" {
printf("TOKEN: LT LEXEME: %s\n", yytext);
return T_LT;
}
">" {
printf("TOKEN: GT LEXEME: %s\n", yytext);
return T_GT;
}
"identifier" {
printf("TOKEN: IDENT LEXEME: %s\n", yytext);
return T_IDENT;
}
{WSPACE} { }
. {
printf("TOKEN: UNKNOWN LEXEME: %s\n", yytext);
return T_UNKNOWN;
}
%%
语法分析器.y
/*
syntaxAnalyzer.y
To create syntax analyzer:
flex file.l
bison file.y
g++ file.tab.c -o file_parser
file_parser < inputFileName
*/
/*
* Declaration section.
*/
%{
#include <stdio.h>
void printRule(const char *lhs, const char *rhs);
int yyerror(const char *s) {
printf("Error!");
}
extern "C" {
int yyparse(void);
int yylex(void);
int yywrap() {return 1;}
}
%}
/*
* Token declarations
*/
%token T_OBRCKT T_CBRCKT
%token T_LT T_GT T_EQ
%token T_IDENT T_UNKNOWN
/*
* Starting point.
*/
%start N_START
/*
* Translation rules.
*/
%%
N_START : N_STATEMENT
{
printRule("START", "STATEMENT");
printf("\n---- Completed parsing ----\n\n");
return 0;
}
;
N_STATEMENT : T_OBRCKT T_EQ T_LT T_IDENT T_GT T_CBRCKT
{
printRule("EXPR", "T_OBRCKT T_EQ T_LT T_IDENT T_GT T_CBRCKT");
}
;
%%
#include "lex.yy.c"
extern FILE *yyin;
void printRule(const char *lhs, const char *rhs) {
printf("%s -> %s\n", lhs, rhs);
return;
}
int main() {
do {
yyparse();
} while (!feof(yyin));
return 0;
}