Skip to content

JSON문자열 분석기 저장소 【 ❴:❵ , ❴:❵ 】🧐

Notifications You must be signed in to change notification settings

O-O-wl/swift-jsonparser

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 

Repository files navigation

JSON 문자열 분석기


객체 한줄 요약

  • GrammerChecker: 입력받은 문자열에 대해 검증을 하는 객체

    • Pattern: jsonObject,jsonList 포맷을 확인하기 위한 내부적으로 재귀적으로 정규표현식패턴을 만들어내는 객체
  • MyTokenizer : 문자열을 토큰화하는 객체

    • Token: 의미를 가진 가장 작은 단위 (단말) enum객체
      • ex) 문자열,숫자,부울,공백,[,]{,},\,,...
    • TokenFactory: 잘게 쪼개진 문자열로 의미를 표현할 수 있는 Token를 생성하는 팩토리객체
  • MyParser : [Token]의 배열을 JsonList,JsonObject로 변환해주는 객체

    • JsonList, JsonObject: swift 기본 콜렉션 자료구조에 JsonValue프로토콜을 채택하여 확장한 타입
  • InputView: 사용자에게 분석할 문자열을 입력받는 뷰 객체

  • OutputView: 파싱된 JSON에 대한 통계분석을 출력하는 뷰 객체


프로젝트를 진행하면서 느낀점

처음시작이 너무 막막했었다.
문자열은 말 그대로 문자열인데 이것을 어떻게 의미를 부여할까? 에 대해 처음 고민을 했다. 그리고 사람은

[ { "name": "부엉이" , "favorites" : [ "샌드위치", "커피"  ], "famous" : "Hello, World" } ]

이런 문자열을 어떻게 쉽게 인식하는지 에 대해 고민을 했다. 그러던 중 "Hello, World" 문자열로 인식하던 이유는 , 가 내가 분석 중인 Context에 따라 사람은 쉽게 다르게 인식한다는 것이었다.
나는 분석중인 Context라는 키워드에 집중하기로 했고, ContextStack의 조합으로 하나의 Parser를 만들어내기 위한 시도를 하였고, 결과적으로 컴파일러의 원리를 공부하게 되었다. 컴파일러는 3가지 단계로 나뉘어진다.
Code - Lexer -> Token - Parser -> AST - CodeGenerator -> Machine Code

나는 Lexer 가 하는 일을 자세히는 알지 못했다. 하지만 목적은 알고 있었다. 어쨋든 의미를 가진 작은 단위로 쪼개는 토큰화를 하는 객체라는 것을 알게 되었고, 객체가 해야할 일과 기대하는 동작이 명확해지는 것을 느꼈고

    MyTokenizer.tokenize(_ :String ) -> [Token]

이것이 곧 인터페이스라는 것을 느꼇다. 그래서 인터페이스를 기반으로 테스트 코드를 작성하기 시작했다.

이 같은 과정으로 객체가 있는 목적에 따른 인터페이스를 분리했고, 인터페이스가 되는 메소드들을 테스트하기 위한 입력과 기대하는 출력을 정리하여, 테스트 코드를 작성했고, 그 결과 private 할 것과 public 할 것이 명확히 나뉘어지는 것 같아서 즐거움을 느꼈다. 객체가 내가 원하는 대로 동작을 하게 되어 테스트가 이쁜 초록색 체크✅ 를 하며 통과를 할 때 희열을 느꼈다.

jsontest

TDD의 맛보기를 본 느낌이었지만, TDD가 이런 이유로 개발에 이로운 점을 줄 수 있는 걸 느껴보는 좋은 경험 이었다.

Parser를 진행할 때 다시 다른 방식도 고민해보았다.

스크린샷 2019-07-09 오후 10 42 19

value에는 array, object로 표현될 수 있는 데 , 또 array, objectvalue를 포함하는 사이클구조였다.

밖에서부터 분석을 하며, 새로운 분석객체(JSONList[],JSONObject{})를 만났을 때 재귀적으로 다시 분석을 시작함으로써, 스택과 유사한 방식으로 분석을 할 수 있다는 것을 느꼈다.

또 ! JSONList[],JSONObject{} 각각의 문법 규칙이 달라서 분석의 차이가 있었다. 스크린샷 2019-07-09 오후 10 42 00 스크린샷 2019-07-09 오후 10 42 06

두개의 분석방식을 적절히 스위칭하며 분석을 하고자 하여 스트래티지패턴이라는 것도 적용해봤다. 스트래티지를 방법은 다음 토큰이 "[,{" 같은 분석의 시작점을 통해 결정되게 하였다.

이 과정이 복잡하게 되어있으면, 컴파일러의 파싱트리(파싱테이블) 과 유사한 형태를 띄게 되지 않을까? 라는 상상도 하게 되었다.

마지막에 swift자료구조의 형태로 파싱된 JSON데이터들을 출력하는 과제가 남아있었다.

객체(JSONList,JSONObject) 각각이 자신의 포맷을 결정하게끔하여 다형메소드로 구현하는 방법이 있었고,

입력된 객체에 따른 형식화를 해주는 별도의 객체(Formatter)를 두는 방법이 있었다.

클린코드 - 로버트.C.마틴책의 말을 빌리자면 두개는 상황에 따라 다르다고 한다. 타입이 계속적인 추가가 있을 형태라면? 그마다 형식화를 하는 객체의 switch문은 고장날 것이고, 커질 것이라는 것이다. 이럴 때는 다형메소드가 더 좋은 방법일 것이다.

하지만

타입보다는 메소드가 추가된다면 모든 객체에 다형메소드가 하나씩 추가되어야 하기때문에 하나의 switch문만 더 추가로 구현하면 되는 여러 객체를 다루는 별도의 객체가 있는 것이 좋을 것이라는 것을 생각하게 되었다.

아직 나는 객체가 자신의 데이터를 최대한 이용하게하는 응집도 높은 객체를 설계하는 데에 익숙하지 않았고, 그것을 경험해보기 위해 다형메소드로 구현을 마무리함으로써 프로젝트는 마무리 되었다!!

실행영상


jsonParser

About

JSON문자열 분석기 저장소 【 ❴:❵ , ❴:❵ 】🧐

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages