2012-11-19 112 views
2

看一看我的語法ANTLR語法變量

grammar protocol; 

options { 
    language = Java; 
    output = AST; 
}      
//imaginary tokens 
tokens{ 
BOOL; 
CHAR; 
STRING; 
} 
parse 
    : declaration 
    ; 

declaration 
    : variable 
    ; 
variable 
    : locals 
    ; 
locals 
    : (bool 
    | char 
    | string)+ 
    ; 
bool 
    :'bool' ID -> ^(BOOL ID) 
    ; 
char 
    : 'char' ID -> ^(CHAR ID) 
    ; 
string 
    :'string' ID -> ^(STRING ID) 
    ; 

ID 
    : (('a'..'z' | 'A'..'Z'|'_')('a'..'z' | 'A'..'Z'|'0'..'9'|'_'))* 
    ; 
INT 
    : ('0'..'9')+ 
    ; 
WHITESPACE 
    : ('\t' | ' ' | '\r' | '\n' | '\u000C')+ {$channel = HIDDEN;} 
    ; 

對於下面的輸入,

bool boolVariable 
char charVariable 
string stringVariable 

我的語法創建以下AST
AST For variables' grammar

我不能聲明一個變量不止一次。我不想申報同一類型的一次用逗號分隔的變量,但我想這樣

bool boolVariable1 
bool boolVariable2 
bool boolVariable3 
string stringVariable1 
string stringVariable2 

這樣做後,我想所有的變量是兩個主要類型。共享和本地。在Java中,共享變量(靜態)是所有對象都具有單一副本的人,而本地變量對每個對象具有不同的副本。我希望用戶在定義變量集之前明確指定變量的範圍。像,

locals: 
    bool boolVariable1 
    bool boolVariable2 
    bool boolVariable3 
    string stringVariable1 
    string stringVariable2 
shared: 
    bool boolVariable4 
    bool boolVariable5 
    bool boolVariable6 
    string stringVariable3 
    string stringVariable4 
    char charVariable1 

而且,是沒有辦法,我可以檢查用戶水溼具有相同名稱的兩個變量什麼辦法?像,

bool boolVariable 
bool boolVariable 

應該給某種錯誤或類似的。 任何想法/幫助?
謝謝

編輯 - 解決方案:

grammar protocol; 

options { 
    language = Java; 
    output = AST; 
}      
//imaginary tokens 
tokens{ 
BOOL; 
CHAR; 
STRING; 
SBOOL; 
SCHAR; 
SSTRING; 
} 
parse 
    : declaration 
    ; 

declaration 
    : variable 
    ; 
variable 
    : (locals 
    | shared)* 
    ; 
locals 
    : 'locals:' (bool| char| string)* 
    ; 
bool 
    :'bool' ID -> ^(BOOL ID) 
    ; 
char 
    : 'char' ID -> ^(CHAR ID) 
    ; 
string 
    :'string' ID -> ^(STRING ID) 
    ; 
shared 
    : 'shared:' (sbool| schar| sstring)* 
    ; 

sbool 
    :'bool' ID -> ^(SBOOL ID) 
    ; 
schar 
    : 'char' ID -> ^(SCHAR ID) 
    ; 
sstring 
    :'string' ID -> ^(SSTRING ID) 
    ; 
ID 
    : (('a'..'z' | 'A'..'Z'|'_')('a'..'z' | 'A'..'Z'|'0'..'9'|'_'))* 
    ; 
INT 
    : ('0'..'9')+ 
    ; 
WHITESPACE 
    : ('\t' | ' ' | '\r' | '\n' | '\u000C')+ {$channel = HIDDEN;} 
    ; 
+0

您可以發佈您的解決方案作爲答案,並自我接受。 – nhahtdh

回答

1

你可以試試這個:

locals 
     : bool* char* string* 
     ; 

應該允許你用同一類型的不同變量的聲明。 最好的(我認爲)禁止用相同名稱聲明不同變量的方法是保持聲明以前變量的集合(Java)。只需調用Java的功能,如here

與問候

+0

通過更改規則,如您所述,我得到「無可行異常」爲每個變量,我聲明多次。 本地和共享變量呢? 此輸入工作正常 布爾boolVariable 布爾boolVariable 焦炭charVariable 但這並不 布爾boolVariable 布爾boolVariable1 焦炭charVariable 串stringVariable –

+0

請查看我的編輯。問題解決了,但我仍然有一個小問題。我可以聲明兩個變量像 布爾boolVariable 布爾boolVariable 但我不能宣佈兩個變量像 布爾boolVariable 布爾boolVariable12 –

+0

沒有與此語法的另一個問題是,你必須總是定義布爾,字符和字符串變量順序 –

1

由於Bahdan在his answer提到的,你要維護一個已被使用的名稱的集合。以下是一個基於更新語法的簡單示例(其他一些更改,請參閱本答案的底部)。新規則var是新成員代碼被使用的地方。請注意,這裏沒有真正的錯誤處理,只是名稱檢查。

grammar protocol; 

options { 
    language = Java; 
    output = AST; 
}      
//imaginary tokens 
tokens{ 
BOOL; 
CHAR; 
STRING; 
SBOOL; 
SCHAR; 
SSTRING; 
} 

@parser::header { 
    import java.util.ArrayList; 
} 

@members { 
    private ArrayList<String> variableNames = new ArrayList<String>(); 

    private boolean variableDefined(String name){ 
     return variableNames.contains(name); 
    } 

    private void defineVariable(String name){ 
     variableNames.add(name); 
    } 
} 

parse 
    : declaration 
    ; 

declaration 
    : variable 
    ; 
variable 
    : (locals | shared)* 
    ; 
locals 
    : 'locals:' (bool| char_ | string)* 
    ; 
bool 
    :'bool' var -> ^(BOOL var) 
    ; 
char_ 
    : 'char' var -> ^(CHAR var) 
    ; 
string 
    :'string' var -> ^(STRING var) 
    ; 
shared 
    : 'shared:' (sbool| schar| sstring)* 
    ; 
sbool 
    :'bool' var -> ^(SBOOL var) 
    ; 
schar 
    : 'char' var -> ^(SCHAR var) 
    ; 
sstring 
    :'string' var -> ^(SSTRING var) 
    ; 
var 
    : ID 
     {!variableDefined($ID.text)}? //This rule is only satisfied if the variable is new. 
     {defineVariable($ID.text);} //we made it here, so it's new. Add it for future reference. 
    ;  
ID 
    : ('a'..'z' | 'A'..'Z'|'_')('a'..'z' | 'A'..'Z'|'0'..'9'|'_')* 
    ; 
INT 
    : ('0'..'9')+ 
    ; 
WHITESPACE 
    : ('\t' | ' ' | '\r' | '\n' | '\u000C')+ {$channel = HIDDEN;} 
    ; 

我可以聲明兩個變量像布爾boolVariable布爾boolVariable但我不能宣佈兩個變量像布爾boolVariable布爾boolVariable12

看到我的變化上面ID。還有一組額外的括號將規則搞亂了。我還將char更名爲char_以使解析器能夠爲我正確編譯。

+0

謝謝。目前我只能以bool,char和string的順序定義變量。我不希望用戶限制,用戶可以以任何順序定義變量。如果我先定義char或string,然後再定義最後的bool,那麼我得到noViableAltException。共享和局部變量(關於訂單)的問題也是如此。我也嘗試將規則更改爲'locals:'bool * char_ * string *,但它甚至無法正常工作。 –

+0

@RizwanAbbasi這很奇怪。這是我的測試輸入:「當地人: 串的 布爾b 炭Ç 串d 布爾Ë 炭˚F 布爾克 共享: 炭X」這產生以下AST:「當地人:(STRING一)( BOOL b)(CHAR c)(STRING d)(BOOL e)(CHAR f)(BOOL g)shared:(SCHAR x)「。確保你的'locals'和'shared'規則以'(bool | char_ | string)*'結尾(順序不重要),而不是'bool * char_ * string *'(順序很重要)。 – user1201210

+0

我試過你的輸入它只適用於共享變量char x的局部變量,它給了我NoViableAltException。此外,如果我嘗試這個命令 分享到: char x 我在AST中獲得單一,沒有更多。我正在使用這種類型的語法(bool | char_ | string)* –