티스토리 뷰
정규표현식이나, Lex&Yacc을 델파이만 개발 하신 분이라면 처음 들어 보신 분들도 계실 것이라고 생각됩니다.
저도 6년 넘게 개발하면서 최근에 알게 되었고, 그 활용 범위가 무궁무진 하다는 것도 알게 되었죠.
이 글을 있는 개발자 분들도 이 글을 계기로 Lex&Yacc에 대해서 관심을 가졌으면 합니다.
Lex&Yacc은 컴파일러를 만들기 위한 도구로 GCC나 대부분의 컴파일러가 Lex&Yacc을 사용하고 있습니다.
Lex&Yacc의 활용 범위는 소스를 분석하거나, 소스에서 주석만 제거하거나, 간단한 스크립트 언어를 만들 수도 있습니다.
C언어나 JAVA의 경우 많은 Lex&Yacc 도구가 많이 있지만 Delphi의 경우 2개 정도 있는 것 같고,
제가 사용하고 있는 Delphi Lex&Yacc은 Tuber Pascal로 만들어 진 것을 델파이용으로 수정한 것으로 버전은 1.3을 사용했습니다.
아래의 예제는 데이터베이스에서 SQL을 파싱하는 아주 간단한 Sample을 만들어 보았습니다.
select aa, bb, cc from tab1, tab2;
위의 SQL 문장에서 컬럼과 테이블 명을 구하는 Lex&Yacc 소스입니다.
위의 SQL 문장의 컬럼과 테이블 명을 구하는 것을 Lex&Yacc을 사용하지 않고도 쉽게 얻어 낼 수 있겠지만, 굉장히 긴 문장의 SQL문장에서 컬럼, 테이블, 함수, 문자열을 분리하는 것을 어려울 것입니다. 이와 같은 SQL문 처리를 위해서 여러분들이 Lex&Yacc문장을 추가 하시기 바랍니다. (인터넷에 SQL grammar 찾아서 추가하면 될 듯......)
▶ Delphi Lex & Yccc Download
http://www.grendelproject.nl/dyacclex/
▶ Lex 파일
- sqllex.l 파일
%%
[F|f][R|r][O|o][M|m] begin return(FROM); end;
[S|s][E|e][L|l][E|e][C|c][T|t] begin return(SELECT); end;
[A-Za-z][A-Za-z0-9_]* begin
yylval.yyString := yytext;
return (NAME); end;
[ \t\n] ;
. |
\n returnc(yytext[1]);
- sqllex.pas 만들기
Delphi Lex - Copyright (c) 2003,2004 by Michiel Rook
Based on Turbo Pascal Lex 4.1, Copyright (c) 1990-2000 Albert Graef
parse ... DFA construction ... code generation ... DONE
15 lines, 6 rules, 27/1200 p, 29/600 s, 58/1200 t.
▶ Yacc 파일
- sqlparser.y 파일
program sqlpser;
{$APPTYPE CONSOLE}
uses
SysUtils,
dlib,
yacclib,
lexlib;
var x : array [1..26] of Real;
%}
%token
%token FROM SELECT /* illegal token */
%%
query_spec:
SELECT selection table_exp ';'
;
table_exp:
from_clause
;
from_clause:
FROM table_ref_commalist
;
table_ref_commalist:
table_ref
| table_ref_commalist ',' table_ref
;
table_ref:
table
| table range_variable
;
range_variable: NAME
;
table:
NAME { writeln('Table : ', $1); }
| NAME '.' NAME
;
selection:
scalar_exp_commalist
| '*'
;
scalar_exp_commalist:
scalar_exp
| scalar_exp_commalist ',' scalar_exp
;
scalar_exp:
column_ref
;
column_ref:
NAME { writeln('Column : ', $1); }
| NAME '.' NAME /* needs semantics */
| NAME '.' NAME '.' NAME
;
%%
{$I sqllex.pas}
var
lexer : TLexer;
parser : TParser;
i : Integer;
begin
for i := 1 to 26 do
x[i] := 0.0;
lexer := TLexer.Create();
parser := TParser.Create();
parser.lexer := lexer;
parser.parse();
end.
- sqlparser.dpr 만들기
Delphi Yacc - Copyright (c) 2003,2004 by Michiel Rook
Based on Turbo Pascal Yacc 4.1, Copyright (c) 1990-2000 Albert Graef
parse ... sort ... closures ... first sets ... LR0 set ... lookaheads ...
code generation ... DONE
89 lines, 18/900 rules, 29/1200 s, 41/9600 i, 33/9600 t, 19/1200 r.
▶ 컴파일, 실행
- 컴파일
위의 lex, yacc 절차를 따르셨다면 sqlparser.dpr, sqllex.pas 파일이 생겼을 것입니다.
sqlparser.dpr, sqllex.pas 한 폴더에 두고 델파이에서 sqlparser.dpr을 열어서 컴파일 하고 sqlparser.exe 실행 하면 됩니다.
select aa, bb from tab;
Column : aa
Column : bb
Table : tab
- Total
- Today
- Yesterday
- Spring
- 전예희
- oracle
- Spring MVC
- 레이싱모델 익스트림 포토 페스티벌
- 일본여행
- android
- BPI-M4
- MySQL
- 송주경
- Linux
- 지스타2007
- 동경
- Delphi
- ffmpeg
- JavaScript
- SAS
- Mac
- flex
- Xcode
- NDK
- 튜닝쇼 2008
- ble
- sas2009
- 서울오토살롱
- Java
- KOBA
- koba2010
- Delphi Tip
- ubuntu
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |