2011-01-13 9 views
0

私は単純な字句解析ツールを書いています。そして私は認識された各トークンに属性を付ける必要性を理解しています。のは、私が得たものを見てみましょう:トークン属性

レクサーで
public sealed class Token 
{ 
    public enum TokenClass 
    { 
     Identifier, 
     StringLiteral, 
     NumberLiteral, 
     Operator, 
     PunctuationSeparator, 
     Bracket, 
     Parenthesis 
    }   
    public TokenClass Class { get; internal set; } 
    public String  Value { get; internal set; } 
} 

私はthier値&クラスを設定するトークンをキュー。しかし、属性についてはどうですか?既存のトークンクラスに関連して機能をどのように設計する必要がありますか?

まず取り払わは私の心に入って来たのだった。

  1. が内部トークンクラス(私はその数が整数と実などが可能性を意味する)「あいまいな-実体」のプライベート抽象クラスを宣言します。
  2. 次に、継承されたクラスを宣言します。 public class Comma : PunctuationSeparator {};
  3. プロパティを追加Object Attribute {get; private set;};
  4. 次に、private void ApplyAttribute()のようなメソッドを作成します。
  5. トークンをインスタンス化してプロパティを設定すると、ApplyAttribute()が呼び出されます。
  6. ApplyAttribute()のように使用してください。 if(CurToken.Attribute is Integer)ような何かを書くのは簡単だろうパーサで

    switch(this.TokenClass) 
    { 
    case this.TokenClass.Number: 
        { 
         this.Attribute = (Int32.TryParse(this.Value))? new Integer() : new Real();     
        } 
    } 
    

。 そうすることを止めることの1つは、私が作成すべきクラスの数です。この解決策は受け入れられますか?

+0

あなたのドメインのオントロジーを持っていますか:

あなたはテランスパーの本(複数可)を見てすることがあります

?異なる種類の空のクラスを作る必要はありません。あなたはすでに相続の構造を作りましたか?おそらく、異なるタイプの 'PunctuationSeperator'を設定すれば十分でしょう。 – Marnix

+0

いいえまだここに記載されているものは作成していません。これらは私の計画と疑問です。それは役に立つと思われるが、クラス... ...私は決定することはできません..助け:)あなたの最後の文をどういう意味ですか? – lexeme

+1

'PunctuationSeperator'のようなクラスを作成するとき。さまざまな引用[カンマ、ピリオド、セミコロ]を使用して、そこにもenumを定義すると便利です。だから最初に、私はあなたがそのようなdescisionを行う前に、あなたのドメインがどのように定義する必要がありますと思います。 – Marnix

答えて

2

私はトークンのために使用したい属性?おそらく

public class Token 
{ 
    public TokenType Type { get ; private set ; } 
    public string Text { get ; private set ; } 
    public int  LineNumber { get ; private set ; } 
    public int  Column  { get ; private set ; } 
} 

public enum TokenType 
{ 
    Keyword : 1 , 
    Integer , 
    String , 
    Whitespace , 
    Comment , 
    ... 
} 

の線に沿って何か私が「価値」へのトークンのテキストの変換に関する以前のポスターで、しかし、反対します。 IMHOは、パーサーのドメインとパーズツリーのノードです。パーサーがコンテキストWRT文法の中にトークンを置くまで、トークンはそれに付けられたラベルを持つ単なるテキストです。字句解析ツールは、下流で何が起こっているのかわかりません(そして、気にする必要があります)。知っている限り、ソーステキストをきれいに印刷しています(この場合、個々のトークンを残しておきたい)。

+0

本を概説しました!ありがとうございます! – lexeme

0

代わりの

public String Value { get; internal set; } 

だけ

public object Value { get; internal set; } 

を使用し、整数または浮動小数点値としてそこに格納整数または浮動小数点値。次に、あなたのパーサーにあなただけの

if (token.Value == null) 
{ 
    // blah 
} 
else if (token.Value is int) 
{ 
    // work with (int) token.Value 
} 
else if (token.Value is double) 
{ 
    // work with (double) token.Value 
} 
else if (token.Value is string) 
{ 
    // work with (string) token.Value 
} 

または代わりを言うことができます。

int? integer; 
double? floating; 
string str; 

if (token.Value == null) 
{ 
    // blah 
} 
else if ((integer = token.Value as int?) != null) 
{ 
    // work with integer.Value 
} 
else if ((floating = token.Value as double?) != null) 
{ 
    // work with floating.Value 
} 
else if ((str = token.Value as string) != null) 
{ 
    // work with str 
} 
+0

これはプリミティブ型ではうまくいきますが、かっこや中括弧はどうですか?どのように私は値を設定するのですか? – lexeme

+0

@helicera:まず、 'object'はプリミティブ型に限定されません。あなたはあなたが望むものを置くことができます。しかし、第二に、かっこトークンにはどのような "価値"が必要ですか?私はnull値を持つ 'OpenParenthesis'と' CloseParenthesis'トークン型があると思います。あるいは、もちろん、 'PunctuationSymbol'トークンタイプを持ち、' ​​'(Value' 'に文字列を格納することもできますが、個人的にはそのハッキーを見つけるでしょう) – Timwi