2013-05-22 18 views
0

我最近開始學習基本的Flex和Bison,因爲我必須爲簡單(但不是太簡單)的語法做一個解析器。我決定在我的語法中製作一個簡化的Java語言。我製作了.l.y文件,並且所有內容都編譯時沒有錯誤(我使用gcc編譯)。 問題是,每次運行生成的程序時,我都會得到Syntax Error,即使使用簡單的輸入,例如:private class Something{}。我沒有得到Syntax Error的唯一時間是當我輸入一個空行(\n)。 我一直在爲此奮鬥了幾天,我懷疑在我的語法中存在問題,但我似乎無法找到它。當然,也可能有其他問題,因爲我對Flex和Bison來說很新。使用Flex&Bison的簡單Java語法

任何幫助將非常感激。

這裏是.l.y文件:

java.l

%{ 
#include "java.tab.h" 
%} 

%option noyywrap 

%% 

"\n" return 0; 
[ \t] ; 

"private" {return PRIVATE;} 
"public" {return PUBLIC;} 
"protected" {return PROTECTED;} 
"implenets" {return IMPLEMENTS;} 
"extends" {return EXTENDS;} 
"class" {return CLASS;} 
"interface" {return INTERFACE;} 
"if" {return IF;} 
"while" {return WHILE;} 
"return" {return RETURN;} 
"true" {return BOOLEAN;} 
"false" {return BOOLEAN;} 

[A-z][a-z0-9]* {return NAME;} 

"\""[A-z0-9]*"\"" {return STRING;} 
"-"?[1-9][0-9]* {return INT;} 

"+"|"-"|"*"|"/"|"="|"==" {return OPERATOR;} 

%% 

java.y

%{ 
#include <stdio.h> 

int cond=0; 
int loops=0; 
int assigns=0; 
int funcs=0; 
int classes=0; 

void yyerror(const char* msg){printf("Error: %s\n", msg);} 
%} 


%token PUBLIC 
%token PRIVATE 
%token PROTECTED 
%token NAME 
%token IMPLEMENTS 
%token EXTENDS 
%token CLASS 
%token INTERFACE 
%token IF 
%token WHILE 
%token STRING 
%token BOOLEAN 
%token OPERATOR 
%token RETURN 
%token INT 

%% 

Code: Class Code | /*empty*/ {printf("classes: %d\n", classes); printf("functions: %d\n", funcs); printf("conditions: %d\n", cond); 
           printf("loops: %d\n", loops); printf("assign operations: %d\n", assigns);} ; 
Class: Modifier ClassType NAME Extra '{' Functions '}' ; 
Modifier: PUBLIC | PRIVATE | PROTECTED ; 
ClassType: CLASS | INTERFACE ; 
Extra: IMPLEMENTS NAME | EXTENDS NAME | /*empty*/ ; 
Functions: Function Functions | /*empty*/ ; 
Function: Type NAME '(' Arguments ')' '{' Commands '}' {funcs++;} ; 
Arguments: Argument Arguments | /*empty*/ ; 
Argument: Type NAME Separator ; 
Type: STRING | INT | BOOLEAN ; 
Separator: ',' | /*empty*/ ; 
Commands: Command Commands | /*empty*/ ; 
Command: Condition | Loop | Assignment | Return ; 
Condition: IF '(' Comparison ')' '{' Commands '}' {cond++;} ; 
Loop: WHILE '(' Comparison ')' '{' Commands '}' {loops++;} ; 
Comparison: NAME OPERATOR INT | NAME OPERATOR NAME | INT OPERATOR NAME ; 
Assignment: NAME '=' Type ';' {assigns++;} ; 
Return: RETURN RetVal ';' ; 
RetVal: NAME | Type ; 

%% 

int main() 
{ 
    yyparse(); 
    return 0; 
} 

回答

2

這裏是一個開始:

首先,所提供的默認規則通過flex只是呼應角色unmatche d通過任何其他規則。 {}不符合任何規則,所以它們會被回聲並且不會被野牛看到,這使得生產Class不可能匹配。一個簡單的解決方案是將默認規則作爲最後一個flex規則:

. { return yytext[0]; } 

其次,[A-z]是不一樣的,因爲[A-Za-z]Za不連續的ASCII碼。我建議使用[[:alpha:]]作爲字母字符,使用[[:alnum:]]作爲字母數字,但[A-Za-z][A-Za-z0-9]沒有任何問題。在這兩種情況下,您可能都想要允許其他字符,如_。 (這不會引起你的任何直接問題,它只是一個說明。)

第三,你拼寫"implements"不正確。

+0

謝謝,這解決了我的問題,這是由於.l文件中缺少默認規則導致的:) – bala

0

對於一般的語法分析器調試,你會發現它很有用-DYYDEBUG編譯解析器(在java.tab.c文件)並調用yyparse堅持前行yydebug=1;到您main功能。

這將導致解析器打印它讀取的所有令牌以及它執行的操作,從而允許您查看它正在執行的操作,並通常顯示正在發生的事情以及爲什麼會收到意外的語法錯誤認爲是正確的。