2015-06-07 15 views
0

我有一個C語言程序,它將表達式轉換爲RPN(反向波蘭語符號)。 我需要做的就是用Flex代替用C編寫的詞法分析器代碼。我已經做了一些工作,但是我遇到了模式方面的問題 - 字或變量ID是特定的。是的,這是課堂練習。ID的彈性模式給出'分段錯誤'

這是我有:

%{ 
    #include "global.h" 
    int lineno = 1; 
    int tokenval = NONE; 
%} 

%option noyywrap 

WS    " " 
NEW_LINE  "\n" 
DIGIT   [0-9] 
LETTER   [a-zA-Z] 
NUMBER   {DIGIT}+ 
ID    {LETTER}({LETTER}|{DIGIT})* 

%% 

{WS}+   {} 
{NEW_LINE}  { ++lineno; } 
{NUMBER}  { sscanf (yytext, "%d", &tokenval); return(NUM); } 
{ID}   { sscanf (yytext, "%s", &tokenval); return(ID); } 
.    { return *yytext;} 
<<EOF>>   { return (DONE); } 

%% 

global.h

#define BSIZE 128 
#define NONE -1 
#define EOS '\0' 
#define NUM 256 
#define DIV 257 
#define MOD 258 
#define ID 259 
#define DONE 260 

所有的工作定義,當我使用數字,括號和運營商,但是當我鍵入例如a+b它給了我Segmentation fault (輸出應該是ab+)。 請不要問我一個解析器代碼(如果真的需要,我可以共享) - 需求是僅使用Flex實現詞法分析器。

+0

不知道flex但我沒有看到'{LETTER}'的條目在哪裏使用? – sln

+0

它在模式中引用ID:'ID {LETTER}({LETTER} | {DIGIT})*',那麼當發現ID模式時,它會運行代碼(並提供錯誤提示) –

回答

2

的問題是,該程序與字符串格式(%s)成整數(&tokenval)的地址做一個sscanf。你應該改變,要的char陣列,例如,

%{ 
    #include "global.h" 
    int lineno = 1; 
    int tokenval = NONE; 
    char tokenbuf[132]; 
%} 

{ID}   { sscanf (yytext, "%s", tokenbuf); return(ID); } 

(雖然strcpysscanf一個更好的選擇,這只是一個起點)。

+0

類型的好點不匹配。儘管它仍然給我相同的錯誤(分段錯誤) –

+0

好的。它出來後,我不得不在更改後更改解析器中的一些代碼。但它現在的作品,謝謝:) –

1

當flex掃描符合模式ID的令牌時,相關操作將嘗試將令牌複製到位置&tokenval處的字符數組中。但tokenval具有類型int,所以

  1. 代碼有未定義的行爲
  2. 如果ID的長度等於或超過一int的尺寸,那麼就可以不適合其所有字節(包括一個字符串結束)在由int佔用的空間。一個合理可能的結果是,你試圖寫過去的結尾,這可能導致段錯誤。
+0

好點。我添加了'char tokenbuf [255];'並更改了{{ID} {sscanf(yytext,「%s」,tokenbuf);回報(ID); }',但它仍然給我同樣的錯誤 –

+0

好的。它出來後,我不得不在更改後更改解析器中的一些代碼。但它現在的作品,謝謝:) –