2011-03-12 4 views
3

--이 주석 행으로 처리됩니다와 선이 시작파서 (lex/yacc)를 만드는 방법은 무엇입니까? 나는 다음과 같은 파일을 갖고있어

--TestFile 
Start ASDF123 
Name "John" 
Address "#6,US" 
end ASDF123 

을 구문 분석 할 필요가있다. 파일은 '시작'을 시작하여 end으로 끝납니다. Start 다음의 문자열은 UserID이고 nameaddress은 큰 따옴표 안에 들어갑니다.

파일을 구문 분석하고 구문 분석 된 데이터를 xml 파일에 기록해야합니다.

이렇게 얻어진 파일

<ASDF123> 
    <Name Value="John" /> 
    <Address Value="#6,US" /> 
</ASDF123> 

이제 상기 파일을 파싱하는 패턴 매칭 (Regular Expressions)를 사용하는 것 같은 것이다. 여기 내 샘플 코드입니다.

/// <summary> 
    /// To Store the row data from the file 
    /// </summary> 
    List<String> MyList = new List<String>(); 

    String strName = ""; 
    String strAddress = ""; 
    String strInfo = ""; 

방법 : ReadFile을

/// <summary> 
    /// To read the file into a List 
    /// </summary> 
    private void ReadFile() 
    { 
     StreamReader Reader = new StreamReader(Application.StartupPath + "\\TestFile.txt"); 
     while (!Reader.EndOfStream) 
     { 
      MyList.Add(Reader.ReadLine()); 
     } 
     Reader.Close(); 
    } 

방법 : FormateRowData

/// <summary> 
    /// To remove comments 
    /// </summary> 
    private void FormateRowData() 
    { 
     MyList = MyList.Where(X => X != "").Where(X => X.StartsWith("--")==false).ToList(); 
    } 

방법 : ParseData

,

방법 :의 WriteFile은

/// <summary> 
    /// To write parsed information into file. 
    /// </summary> 
    private void WriteFile() 
    { 
     XDocument XD = new XDocument(
          new XElement(strInfo, 
             new XElement("Name", 
              new XAttribute("Value", strName)), 
             new XElement("Address", 
              new XAttribute("Value", strAddress)))); 
     XD.Save(Application.StartupPath + "\\File.xml"); 
    } 

렉스와 Yacc에를 사용하여 파서를 작성하도록 도와주세요 ParserGenerator

들었습니다. 그 이유는 내 기존 파서 (Pattern Matching)가 유연하지 않기 때문입니다. 올바른 방법이 아닙니다 (나는 그렇게 생각합니다).

나는 ParserGenerator을 사용하는 방법 (나는 Code Project Sample OneCode Project Sample Two을 읽었으나 아직도이 것에 익숙하지 않다). C# 파서를 출력하는 파서 생성기를 제안 해주십시오.

답변

5

Gardens Point LEXGardens Point Parser Generator은 LEX 및 YACC의 영향을 크게받으며 C# 코드를 출력합니다.

귀하의 문법은 귀하의 현재 접근 방식이 좋다고 생각하기에 충분히 간단하지만 "실제"하는 방식을 배우려는 명성이 있습니다. :-) 그래서 여기에 문법에 대한 제안이있다. (실제 규칙과는 다르다.) 실제 GPPG 파일은 문법 트리를 만들기 위해 C# 코드로 ...을 대체해야하고 토큰 선언 등이 필요하다.) 설명서의 GPPG 예제를 읽고 당신은 또한 토큰을 설명 GPLEX 파일이 필요합니다.

/* Your input file is a list of "top level elements" */ 
TopLevel : 
    TopLevel TopLevelElement { ... } 
    | /* (empty) */ 

/* A top level element is either a comment or a block. 
    The COMMENT token must be described in the GPLEX file as 
    any line that starts with -- . */ 
TopLevelElement: 
    Block { ... } 
    | COMMENT { ... } 

/* A block starts with the token START (which, in the GPLEX file, 
    is defined as the string "Start"), continues with some identifier 
    (the block name), then has a list of elements, and finally the token 
    END followed by an identifier. If you want to validate that the 
    END identifier is the same as the START identifier, you can do that 
    in the C# code that analyses the syntax tree built by GPPG. 
    The token Identifier is also defined with a regular expression in GPLEX. */ 
Block: 
    START Identifier BlockElementList END Identifier { ... } 

BlockElementList: 
    BlockElementList BlockElement { ... } 
    | /* empty */ 

BlockElement: 
    (NAME | ADDRESS) QuotedString { ... } 
1

먼저 파서의 문법을 정의해야합니다.어휘 분석 할 렉스 될 수행합니다

file : record file 
    ; 

record: start identifier recordContent end identifier {//rule to match the two identifiers} 
     ; 

recordContent: name value; //Can be more detailed if you require order in the fields 

: (Yacc에 부분)

뭔가처럼 좋아 보인다. 그리고 당신의 정규식이 그들을 정의하는 데 유용 할 것 같아요.

내 대답은 대략적인 초안이므로 인터넷을 통해 lex/yacc flex/bison에 대한보다 완벽한 자습서를 찾은 다음 더 집중된 문제가있는 경우 여기로 돌아와보십시오.

관리되는 코드를 유지할 수있는 C# 구현이 있는지 여부도 알 수 없습니다. 관리되지 않는 C/C++ 가져 오기를 사용해야 할 수 있습니다.