2013-07-26 38 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,字符類中唯一具有特殊含義的字符是-,^](但我可能是錯的)。

相關問題