2010-09-11 106 views
2

我必須創建一個類似c語言的詞法和語法分析器。在這種語言中,我們將其定義爲「在符號%之後存在的所有內容,直到行結束」。以下聲明是否正確?定義評論和引用flex和野牛和詞彙錯誤

Flex 
... 
[%][^\n]*[\n] { return T_COMMENT; } 
[\n] { return T_NEWLINE; } 

Bison 
... 
comment:com text newline; 
text: |name text|digit text; 

... 
com: T_COMMENT { printf("%s",yytext); }; 
newline: T_NEWLINE { printf("%s",yytext); }; 

我還需要定義引用符號」。是下列正確的是(柔性)?

"\"" { return T_QUOTE; } 

有一個在flex和野牛輸入文件沒有編譯錯誤,但是當我使用一個程序用這種類似C語言編寫的測試輸入,我得到了第1行的詞彙錯誤。這一行沒有詞彙錯誤。我的程序必須從這樣開始: 程序name_of_program和一個包含新行 I做出以下聲明: Flex

"PROGRAM" { return T_PROGRAM; } 

野牛

%start programma 
%token T_PROGRAM 
... 
programma:PROGRAM name newline function STARTMAIN dec_var command ENDMAIN eof; 
... 
PROGRAM: T_PROGRAM { printf("%s",yytext); }; 
... 

(以大寫單詞的定義就像節目裏,是語言的一部分) 難道我寫的東西錯了嗎?我認爲問題在於換行定義,但我不確定。

非常感謝您的回覆。對不起,很長的職位。

回答

2

通常,註釋由詞法分析器處理,不傳遞給解析器。如果你的語言真的是C語言,那麼在大多數情況下,換行符應該像其他任何空格一樣對待。評論和引用的字符串是值得注意的例外。引號字符串通常由詞法分析器使用開始狀態捕獲並傳遞給解析器。

您的flex代碼使用的字符集太多。如果你只想匹配一個特定的字符,你不需要創建一個集合;只需放置該字符,如果需要,可以使用反斜槓轉義。此外,.表示任何非換行符。

此外,您還沒有任何關於name_of_program令牌的定義。假設它是一個C風格的標識符,你可以在Flex中聲明一個標識符模式和標記並將其傳遞給野牛。

最後,您可能希望採用使用全部大寫的命名約定來傳遞從bison到bison的令牌,而在bison中使用小寫形式的令牌。

所以,從你所描述的東西,我有以下幾點:

example.l:

%% 

\%.* /* comment */ 
\n { return T_NEWLINE; } 
\' { return T_QUOTE; } 
PROGRAM { return T_PROGRAM; } 
[A-Za-z_][A-Za-z0-9_]* { yylval.id = yytext; return T_IDENTIFIER; } 

%% 

example.y:

%% 

programma: T_PROGRAM T_IDENTIFIER T_NEWLINE function STARTMAIN dec_var command ENDMAIN eof; 

text: 
    | name text 
    | digit text; 

%% 

我不知道你在那裏需要eof令牌。

我希望這會有所幫助。