3

私の文法を見てください

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変数の文法用

変数を複数回宣言することはできません。同じタイプの変数をコンマで区切って一度に宣言したくないのですが、このようにしたい

bool boolVariable1
bool boolVariable2
bool boolVariable3
string stringVariable1
string stringVariable2

これを行った後、すべての変数を2つの主要なタイプにします。共有およびローカル。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

さらに、ユーザーが同じ名前の2つの変数を持つことができないことを確認する方法はありますか?好き、

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;}
    ;
4

2 に答える 2

1

これを試すことができます:

  locals
      :  bool* char* string*
      ;

同じ型の異なる変数の宣言を許可する必要があります。同じ名前の異なる変数の宣言を禁止する最善の (私が思うに) 方法は、以前に宣言された変数を使用して (Java で) コレクションを保持することです。ここのようにJava関数を呼び出すだけです

敬具

于 2012-11-19T13:18:19.863 に答える
1

Bahdan が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;}
    ;

bool boolVariable bool boolVariable のように 2 つの変数を宣言できますが、bool boolVariable bool boolVariable12 のように 2 つの変数を宣言することはできません

上記の変更を参照してくださいID。ルールを台無しにする余分な括弧のセットがありました。また、パーサーが正しくコンパイルされるように名前を に変更charしました。char_

于 2012-11-19T22:26:29.153 に答える