Delphi Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
델파이 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
FreePascal/Lazarus
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
델마당
볼랜드포럼 광고 모집

델파이 팁&트릭
Delphi Programming Tip&Tricks
[208] Oracle SQL 파서를 만들면서...
동그라미 [bluexmas] 9561 읽음    2007-04-23 10:43
Oracle SQL 파서를 만들면서...

Oracle SQL 문장을 파싱하는 파서를 만들면서 저와 같은 고민은 하는 개발자 분께서 계실 것 같아서 글을 올립니다.

파서를 만들기 위해서는 Grammar파일을 만들어야 하는데,
취미로 시작한 SQL 파서에 Oracle 문장 전부를 해석 하기 위한 Grammar을 만들기에는 시간과 노력이 많이 필요합니다.

그 때문에 인터넷에서 가장 Oracle SQL 문장 잘 표현한 Grammar을 찾다가 http://www.programmar.com/grammars.htm 에서 다운 받을 수 있는 Grammar가 가장 잘 표현되어 있는 것 같았습니다.

이 Grammar을 델파이용 Lex & Yacc - dyacclex (http://www.grendelproject.nl/dyacclex/) 형식으로 변환해서 Code Generator 해보았지만 Yacc 문장에 오류가 많아 변환 할 수 없었습니다.

그때 생각으로는 델파이에서 제공하는 dyacclex 자체가
지원하는 기능이 약해 변환을 하지 못하는 것이구나 생각해서, 다른 델파이용 Lex & Yacc을 찾아본 결과 Coco/R for Delphi (http://www.tetzel.com/CocoR/)을 찾았고, 또 Coco/R 용으로 Grammar을 변환 하여 Code Generator 해보았지만, 또 Yacc 문법에 오류가 많아서 변환 수 없었습니다.

C++ 파서인 Parser Generator(http://www.bumblebeesoftware.com/), ANTLR, Java 파서인 JavaCC가 지원하는 Grammar 파일로 변환해서 Code Generator 해보았지만 Yacc에 오류가 발생하였습니다.

처음부터 Grammar파일에 문제가 있다는 것을 그때야 알았습니다.

http://www.programmar.com/grammars.htm 여기에서 제공된 Grammar는
Oracle에서 제공되는 매뉴얼(http://www.cs.uvm.edu/oracle9doc/server.901/a90125/statements_63.htm)에 나온 Grammar을 표현한 것이고, Oracle에서 제공되는 매뉴얼은 사람이 Grammar을 보기 편하게 만들어 졌다는 결론을 내렸습니다.

예를 들면

From :=
  table | view;

table :=
  lex_identifier;

view :=
  lex_identifier;

From 문장 뒤에 Table 명이나 View 명이 올 수 있는데,
http://www.programmar.com/grammars.htm 에서 제공되는 Grammar는 Table명 또는 View명을 표기 하고 있지만, 지금까지 보아온 Lex & Yacc 툴은 From 다음에 Table명이 오거나 View명이 오거나 어차피 하나의 lex_identifier가 오는 것이고, Lex & Yacc 자체는 Table명인지 View명인지 알 수 없기에 Yacc 문법오류가 발생 했던 것입니다.

위에 있는 문장을 Yacc이 해석 가능하게 하려면 아래 같은 형식으로 수정해야 됩니다.

From :=
  table_or_view;

table_or_view :=
  lex_identifier;

그래서 다시 작업했습니다. Lex & Yacc 형식으로 Grammar을 변환하자.
그러나 너무 많은 문장과 테스트 없이 이 많은 문장을 변경할 수는 없었습니다.

최종 결론은 Yacc을 만들기로 결심했습니다.
예전에 로봇 쥐가 길을 찾아가는 프로그램을 한적이 있는데, 한 번 들어간 길을 기록해 두었다가 들어온 입구로 다시 들어가지 않는 방법으로 길을 찾는 프로그램인데, 이와 비슷한 방식으로 문장을 해석하도록 구현 했습니다.

완벽하지는 않지만 어느 정도 해석이 가능한 SQL 파서를 만들었습니다.

첨부한 파일에 plsql.sh.gdl 을 보시면, 아래와 같은 문장을 찾을 수 있는데,

query_table_expression ::=   
    [schema "."]
      ( table /. ShowMessage('from table = ' + GetValueToken(actioninx).yystring); ./ [ (  "PARTITION" "(" partition ")"
                   | "SUBPARTITION" "(" subpartition ")"
                ) [sample_clause]
               | "@" dblink
                 | sample_clause
              ]
         | { view } ["@" dblink]
      )
    | "(" subquery [subquery_restriction_clause] ")"
    | query_name
    ;

여기에서 아래와 같이 from 다음에 테이블 명이 오면 그 테이블 명을 ShowMessage 하도록 하였습니다.

/. ShowMessage('from table = ' + GetValueToken(actioninx).yystring); ./

plsqlYacc.pas 파일의 내용 일부

procedure TplsqlYacc.DoAction(yyruleno : integer; actioninx : integer);
begin
  (* actions: *)
  case yyruleno of
    0: begin
ShowMessage('from table = ' + GetValueToken(actioninx).yystring);
    end;
  end;
end;

이제 SQL 파싱은 했는데, 파싱한 결과를 가지고 질의문 튜닝이나, SQL 문장을 리포트 하는 코드를 추가하려면, 아직 해야 할 일이 많이 남아 있네요.

지금까지 테스트한 프로그램과 소스 일부를 첨부합니다.
SQL 파서를 만드는데 조언이 필요하시면 메일주세요.

쓰다 보니 제 자랑이 되었네요.
문제가 있으면 관리자 님께서 지워주세요.
김모씨 [testcode]   2019-12-04 11:01 X
성지 순례 왔습니다. 부자 되게 해주세요!
오랑캐꽃 [oranke]   2019-12-04 13:32 X
저도 성지순례 왔습니다. 꾸우벅~

+ -

관련 글 리스트
208 Oracle SQL 파서를 만들면서... 동그라미 9561 2007/04/23
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.