2011-01-13 2 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; } 
} 

나는, 자신의 가치 & 클래스를 설정 토큰을 큐에 넣습니다. 그러나 속성은 어떻습니까? 기존 토큰 클래스를 기준으로 기능을 어떻게 디자인해야합니까?

먼저 문질러서 내 마음에 와서이었다 :

  1. 내부 토큰 클래스 (내가 그 수는 정수 및 실제 등이 될 수 의미) "모호한-기관"의 개인 추상 클래스를 선언;
  2. 그런 다음 상속 된 클래스를 선언합니다. public class Comma : PunctuationSeparator {};
  3. 재산 추가 Object Attribute {get; private set;};
  4. 그런 다음 private void ApplyAttribute()과 같은 메서드를 만듭니다.
  5. 토큰이 인스턴스화되고 속성이 설정되면 ApplyAttribute()으로 전화하십시오.
  6. ApplyAttribute()과 같은 것을 사용하십시오. 파서에서

    switch(this.TokenClass) 
    { 
    case this.TokenClass.Number: 
        { 
         this.Attribute = (Int32.TryParse(this.Value))? new Integer() : new Real();     
        } 
    } 
    
는 그 if(CurToken.Attribute is Integer) 뭔가를 작성하는 쉬운 것입니다. 내가 그렇게해야하는 것을 막을 수있는 한 가지는 내가 만들어야하는 수업의 수입니다. 이 해결책이 수용 가능한가? 대신

public String Value { get; internal set; } 

+0

도메인의 온톨로지가 있습니까 :

당신은 테 런스 파의 책 (들)을 살펴 할 수 있습니다

? 다른 종류의 빈 클래스를 만들어야 만하는 것은 아닙니다. 이미 상속 구조를 만들었습니까? 어쩌면 다른 유형의 'PunctuationSeperator'를 설정하는 것만으로 충분합니다. – Marnix

+0

아니요 여기에 설명 된 내용을 아직 작성하지 않았습니다. 이것들은 단지 나의 계획과 의심입니다. 유용하게 보이지만 수업은 ... 내가 결정할 수는 없어. 도움 : 마지막 문장을 말하는 것이 무슨 뜻이야? – lexeme

+1

'PunctuationSeperator'와 같은 클래스를 생성 할 때. 서로 다른 puctuations [comma, period, semilocon]로 열거 형을 정의하는 것이 편리 할 수 ​​있습니다. 그래서 먼저, 그러한 판단을 내리기 전에 도메인을 정의해야한다고 생각합니다. – 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, 파서의 도메인과 파스 트리의 노드입니다. 구문 분석기가 문맥에 문맥을 놓을 때까지 토큰은 레이블이 붙은 텍스트 조각입니다. 어휘 분석기는 다운 스트림에서 일어나는 일을 알지 못합니다 (알고 있어야합니다). 알다시피, 원본 텍스트는 예쁜 텍스트로 인쇄됩니다 (이 경우 개별 토큰 만 남기고 싶음).

+0

책을 개관했습니다! 고마워요! – lexeme

0

단지

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 : 첫째, '객체'는 원시 타입에 국한되지 않습니다. 원하는 모든 것을 넣을 수 있습니다. 그러나 둘째, 괄호 토큰에 어떤 "가치"가 필요합니까? null 값을 가진'OpenParenthesis'와'CloseParenthesis' 토큰 타입이있을 것으로 기대합니다. 물론,'PunctuationSymbol' 토큰 타입을 가질 수도 있고'Value'에 문자열을 저장할 수도 있습니다. 그러나 개인적으로 나는 그 해키를 발견 할 것입니다. – Timwi