2013-07-26 29 views
0

我希望Lex在给出“foo + 1”的输入时首先返回标识符“foo”,然后返回字符“+”,然后返回整数1。如果我使用“foo + 1”,这可行,但由于某种原因使用语法,如果我省略空格,则不起作用,它跳过'+',只返回“foo”,然后是1。我无法弄清楚为什么。这里有什么东西似乎有问题吗?Lex只在它们之间有空格时检测符号

%{ 
#include "expression.h" 
#include "picoScanner.h" 
static int block_comment_num = 0; 
static char to_char(char *str); 
int yylineno = 0; 
%} 

%option nodefault yyclass="FlexScanner" noyywrap c++ 


%x LINE_COMMENT 
%x BLOCK_COMMENT 

%% 

Any      { return pico::BisonParser::token::ANY; } 
Int      { return pico::BisonParser::token::INT; } 
Float     { return pico::BisonParser::token::FLOAT; } 
Char     { return pico::BisonParser::token::CHAR; } 
List     { return pico::BisonParser::token::LIST; } 
Array     { return pico::BisonParser::token::ARRAY; } 
Table     { return pico::BisonParser::token::TABLE; } 
alg      { return pico::BisonParser::token::ALG; } 
if      { return pico::BisonParser::token::IF; } 
then     { return pico::BisonParser::token::THEN; } 
else     { return pico::BisonParser::token::ELSE; } 
is      { return pico::BisonParser::token::IS; } 
or      { return pico::BisonParser::token::OR; } 
and      { return pico::BisonParser::token::AND; } 
not      { return pico::BisonParser::token::NOT; } 
when     { return pico::BisonParser::token::WHEN; } 
[A-Z][a-zA-Z0-9_]*  { yylval->strval = new std::string(yytext); 
          return pico::BisonParser::token::TYPENAME; } 
[a-z_][a-zA-Z0-9_]*  { printf("saw '%s'\n", yytext); yylval->strval = new std::string(yytext); 
          return pico::BisonParser::token::ID; } 
"=="     { return pico::BisonParser::token::EQ; } 
"<="     { return pico::BisonParser::token::LEQ; } 
">="     { return pico::BisonParser::token::GEQ; } 
"!="     { return pico::BisonParser::token::NEQ; } 
"->"     { return pico::BisonParser::token::RETURN; } 
[\+\-\*/%]    { return yytext[0]; } 

[-+]?[0-9]+    { yylval->ival = atoi(yytext); 
          return pico::BisonParser::token::INT_LITERAL; } 
([0-9]+|([0-9]*\.[0-9]+)([eE][-+]?[0-9]+)?) { yylval->fval = atof(yytext); 
               return pico::BisonParser::token::FLOAT_LITERAL; } 
\"(\\.|[^\\"])*\"  { yylval->strval = new std::string(strndup(yytext+1, strlen(yytext) - 2)); 
          return pico::BisonParser::token::STRING_LITERAL; } 
\'(\\.|[^\\'])*\'  { yylval->cval = to_char(yytext+1); 
          return pico::BisonParser::token::CHAR_LITERAL; } 
[ \t\r]+    { /* ignore */ } 
\n      { yylineno++; } 
.      { printf("~~~~~~~~~~munched %s\n", yytext); return yytext[0]; } 

%% 

static char to_char(char *str) { 
    if (strlen(str) <= 1) { 
     fprintf(stderr, "Error: empty character constant (line %d)\n", yylineno); 
     exit(1); 
    } else if (str[0] != '\\') { 
     return str[0]; 
    } else { 
     if (strlen(str) == 1) { 
     fprintf(stderr, "Error: somehow we got a single slash character\n"); 
     exit(1); 
     } 
     switch (str[1]) { 
     case 'n': return '\n'; 
     case 'r': return '\r'; 
     case 't': return '\t'; 
     case 'a': return '\a'; 
     case 'b': return '\b'; 
     case 'f': return '\f'; 
     case 'v': return '\v'; 
     case '\'': return '\''; 
     case '"': return '"'; 
     case '\\': return '\\'; 
     case '?': return '\?'; 
     case 'x': 
      fprintf(stderr, "Error: unicode not yet supported (line %d)\n", yylineno); 
      exit(1); 
     default: 
      fprintf(stderr, "Error: unrecognized escape sequence '\\%c' (line %d)\n", 
                    str[1], yylineno); 
      exit(1); 
     } 
    } 
} 

回答

2

我不familair有法,但我敢肯定,以下将导致错误:

[-+]?[0-9]+    { yylval->ival = atoi(yytext); 
         return pico::BisonParser::token::INT_LITERAL; } 

foo解析为一个标识,但随后“+0”被解析为int文字(由于atoi转换,该符号被丢弃)。

这可能是在词法水平只考虑无符号数字文本,并在语法分析器(治疗+-标记不同,这取决于它们的上下文)的水平处理的迹象是个好主意。 这不仅解决了歧义,而且它还使您能够“正确地”(在C,C++,Java等中这些是合法的)解析整数文字,如- 5而不是-5

此外:算术运算符规则中的转义反斜杠是否真的有必要? Afaik,字符类中唯一具有特殊含义的字符是-,^](但我可能是错的)。

相关问题