2017-08-19 12 views
-1

私はコンパイラを作成しています。プロパティに値を設定します

public sealed class Token 
    { 
     public TokenType Type { get; private set; } 
     public string Lexeme { get; private set; } 
     public int CurrentLine { get; private set; } 

     public Token(TokenType type, string lexeme, int currentLine) 
     { 
      Type = type; 
      Lexeme = lexeme; 
      CurrentLine = currentLine; 
     } 
    } 

TokenTypeは、私は別のトークンタイプを持っている列挙型である:私はToken定義を次のようしています。

public enum TokenType 
    { 

     // keyword 
     PrintKeyword, 
     VarKeyword, 
     //... 

     // literal 
     IntegerLiteral, 
     //... 

     // identifier 
     Identifier, 

     //... 
    } 

トークナイザは、パーサーにトークンのストリームを渡し、パーサが抽象構文ツリーを生成し始めます。私の実装では、各ノードタイプに対して1つのクラスがあります。

class Operand 
    { 
     Token token { get; set; } 
      //Token.Type 
       //IntegerLiteral || Identifier 

    } 

    class Term 
    { 
     Token termOperator { get; set; } 
      //Token.Type 
       //Multiplication || Division 
     Operand termOperand1 { get; set; } 
     Operand termOperand2 { get; set; } 

    } 

    //... 

ご覧のとおり、クラスの1つはOperandで、パーサーが指定したトークンを格納します。 <OperandObjHere>.tokenIntegerLiteralまたはIdentifierしか受け入れないように、どうすれば保護できますか?セットメソッドでそれを唯一の方法でチェックしていて、ルールと一致しない場合に例外をスローしますか?それはベストプラクティスですか?私はまた、各ノードタイプのための別のクラスを作成する方法が行くかどうか知りたいですか?

+1

アーチに何か問題があると感じます。多分あなたのコードをより多面的にする必要があります。容認できない値をフィルタリングしようとすると奇妙に見えるからです。 –

+0

パーサーは、タームになると思われるトークンの1つを見つけた後にのみパーサーを作成するため、不正なタームを作成することはありません。 – harold

+0

この質問は非常に幅広く、特にこれが何か解決すべき価値があることを示す良い[mcve]がなければ([このコメント](https://stackoverflow.com/questions/45775416/restrict-values-set-to-the -property#comment78509140_45775416))。また、解決する必要がある場合は、 'Token'プロパティが基本型(例えば、"ノード ")の仮想メンバであり、各サブクラスが独自の制限を適用することができる、多態的なアプローチが優れていることに同意します。設定者または明示的なフィルタリングメカニズム(例えば、有効な値の保護されたコレクション)を介して実装されます。 –

答えて

1

Tokenプロパティのsetで確認できます。 C#7構文を使用します。

class Operand { 

    private Token token; 

    Token Token { 
     get => token; 
     set => token = (value.Equals(TokenType.IntegerLiteral) || value.Equals(TokenType.Identifier)) ? value : throw new Exception("Token must be IntegerLiteral or Identifier"); 
    } 
} 
+0

私が言ったように、私は代わりの方法を探しています: "それを設定方法で唯一の方法でチェックして、ルールと一致しない場合に例外をスローしますか?"また、各ノードタイプごとに別々のクラスを作成していますか? – 107MP

+0

このようにしたくない理由はありますか?無効な値に対して期待される動作は何ですか?私が知る限り、コンパイル時に 'enum 'を制限することはできません。有効な値しか持たない別の 'enum'を使うこともできますが、何らかのチェックや変換が必要です。 –

+0

これは本当に必要ではありませんが、将来の開発のために悪意のあるトークンを割り当てるのを防ぐ方が良いと思います。 – 107MP

関連する問題