제멋대로 막 정리
헤헤
-= pglex program =-
만든놈: 성대아싸
1. pglex란?
- pglex 는 일종의 lex 프로그램 입니다. 일련의 문자열 인풋을
원하는 요소(Token)로 딱딱 끊어주는 프로그램을 스캐너라고 하는데 이 스캐너를
만드는 것을 도와주는 프로그램입니다. 즉 프로그램을 만드는 프로그램입니다.
- 만든 이유는 컴파일러 수업때 flex를 사용하지 말래서 빡쳐서 만들었던
초기버젼이 있었습니다. 너무 허접해서 계속 찝찝한 기분이 남아있어서 그냥
개량하여 만들게 되었습니다.
- Programming Gallery를 기념하여 약자를 따서 pglex라고 이름붙였습니다.
-
2. pglex 사용대상
- 컴파일러 수업을 듣는 대딩, 스캐너 구현 플젝 임박한 대딩
- 심심한 분
- 얼마나 pglex가 허접한지 까고 싶으신 분
3. pglex 사용법
3.1 실행방법
(1) pglex file을 작성합니다. 텍스트 파일이면 확장자 상관없습니다.
(2) 커맨드 창에서
pglex 작성한파일
을 입력하면 pgout.c 파일이 자동으로 생성 됩니다.
3.2 lex퍄일 작성방법
(1) c언어 프로그램 작성할 때는 크게
정의
함수 구현
처럼 작성하는데 원하는 토큰을 인식하는 함수를
pglex가 자동으로 만들어 주는 겁니다. 고로
정의부
%%
정규식1 액션코드(c언어)
정규식2 액션코드
....
%%
함수구현
즉 %%과 %% 사이 부분을 pglex가 인식해서 c언어 함수로 만듭니다.
(2) 구분자 %%
- 구분자 %%는 앞뒤로 어떤문자라도 (심지어 공백(스페이스,탭))
오면 안됩니다.
그 라인에 %% 만 있어야 pglex가 인식합니다.
(3) 정규식
- 정규식은 반드시 줄의 맨 앞부터 써야 합니다.
- 정규식 앞에 공백 문자가 있으면 안됩니다.
(4) 액션코드
- 액션코드는 반드시 정규식과 같은라인에만 있어야 합니다.
- 액션코드를 여러줄로 쓰고 싶으면 함수를 따로 만들고
그걸 호출하게 하세요.
- 정규식과 액션코드는 공백으로 구분됩니다.
고로 정규식 안에서는 공백(스페이스, 탭) 쓸 수가 없습니다.
참고로 pglex정규식에서 스페이스는 \'\\s\', 탭은 \'\\t\', 로 씁니다.
(5) 사용자정의부, 함수구현부
- 알아서 작성하세요
3.3 pg_ 변수 및 함수들
- pgout.c 파일이 만들어지면 내부적으로 사용하는 변수,함수들이 만들어집니다.
이것들은 앞에 pg_ 가 붙습니다.
- pg_input : 파일 포인터 입니다. 스캔할 대상을 지정하면 됩니다.
따로 초기화하지 않으면 pg_lex() 함수를 사용할때 stdin 으로 지정됩니다.
- pg_token : 문자열배열 입니다. 정규식에 매칭되면 해당 정규식에 매칭된
토큰이 저장됩니다. 알아서 가공해서 쓰면 댑니다.
- pg_lex() : 함수 입니다. 이 함수를 호출하면 스캔할 대상을 가지고
스캔을 실시합니다. EOF 가 입력될 때까지 스캔합니다.
- 그외 pg_ 변수들 : 안 건드리는것이 좋으나 스캐너 구조를 다르게 하고 싶으면
알아서 고쳐 쓰세요
3.4 사용예제
- 참조하세요
4. pglex 가 지원하는 정규식
- 엥간한 정규식과 비슷합니다. dfa 기반이라 nfa엔진에서 지원하는
캡쳐, 룩어라운드 같은 기능은 없습니다.
참조:
nfa엔진) perl, php, java에서 regex 패키지? , c# , .....
dfa엔진) lex계열, grep계열, ...
4.1 일반문자
그냥 문자에 매치됩니다.
예) 정규식 abc 는 문자열 "abc" 에 매치됩니다.
4.2 유니온
| 문자로 구분하면 앞에놈 또는 뒤엣놈에 매치됩니다.
예) 정규식 abc|de 는 문자열 "abc" 혹은 "de"에 매치됩니다.
4.3 괄호
정규식을 괄호로 묶어서 하나의 단위로 표현할 수 있습니다.
예) 정규식 l(ik|ov)e 은 문자열 "like" 혹은 "love"에 매치됩니다.
4.4 수량자
*,+,? 문자들을 사용하면 반복과 같은 개념을 표현할 수 있습니다.
(1) 수량자 *
바로 앞 대상을 0번 이상 반복합니다.
예) 정규식 ab*c 는 문자열 "ac", "abc", "abbc", "abbbc",....
(2) 수량자 +
바로 앞 대상을 1번 이상 반복합니다.
예) 정규식 a(bc)+d 는 문자열 "abcd", "abcbcd", "abcbcbcd", "abcbcbcbcd", ....
(3) 수량자 ?
바로 앞 대상이 있을수도 있지만 없어도 됩니다
예) 정규식 ab?c 는 문자열 "ac" 혹은 "abc" 에 매치됩니다.
4.5 문자 클래스
[와 ] 로 여러개의 문자를 묶어서 그중 하나에 매치됩니다.
(1) 단일 문자 쓰기
문자클래스로 묶인 단일문자들중 하나에 매치됩니다.
예) 정규식 [akz] 는 문자열 "a" 혹은 "k", 혹은 "z"에 매치됩니다.
(2) 문자 범위 쓰기
문자-문자 같이 쓰면 첫번째 문자와 두번째 문자
사이에 있는 문자들(범위)에 매치됩니다.
예) 정규식 [a-z0-9] 는 a에서 z까지 사이의 문자 혹은 0에서 9까지 사이 문자에
매치되므로 문자열 "a", "b",..."z", "0","1",..."9" 에 매치됩니다.
(3) 부정문자 ^
문자 클래스를 사용할때 [ 다음에 바로 ^ 를 쓰면
\'문자클래스에 포함이 되지 않는 것!\' 에 매치됩니다.
예) 정규식 [^aeiou] 는 각각의 문자 a,e,i,o,u 가 아닌 다른 문자들에 매치됩니다.
이는 범위에도 마찬가지로 적용됩니다.
예) 정규식 [^0-9] 는 \'숫자가 아닌것\' 에 매치됩니다.
(4) 문자클래스 안에서 [, ], -, ^ 문자 사용하고 싶을때
[,],- 문자들은 문자클래스를 구성하는데 쓰이므로 저 문자 자체를 매치시키고
싶을 때는 앞에 \\ 문자를 붙여서 이스케이프(특수기능으로부터 탈출) 시켜줍니다.
예) 정규식 [\\[\\]\\-] 는 문자열 "[" 혹은 "]" 혹은 "-" 에 매치됩니다.
^ 문자를 사용하고 싶으면 그냥 맨 처음에 안 써주면 됩니다.
예) 정규식 [a^] 는 문자열 "a", "^" 에 매치됩니다.
4.6 특수 문자
. 문자는 \'모든 문자\' 를 의미합니다. (아스키코드 1번부터 127번)
예) 정규식 a.*b 는
a로 시작하면서 중간에 0개이상의 어떤문자라도 오지만
반드시 b로 끝나는 문자열들에 매치됩니다.
"ab","arikkjfwb", "a$((FDKJkdjfkw9348 b", ......
4.6 이스케이프
(1) 정규식에서 사용되는 특수문자들 자체를 매치시키고 싶을때
유니온 |
괄호 ()
수량자 *, +, ?
문자클래스 [, ]
모든 문자 .
그 문자들 앞에 \\ 문자를 붙여서 이스케이프(특수기능 탈출) 시켜줍니다.
예) \\|, \\(, \\), \\*, \\+, \\?, \\[, \\], \\.
(2) pglex에서 사용되는 특수문자들
공백 스페이스,탭,라인피드
구분자 %%
같은 경우 pglex에서 쓰이므로 이 문자들 자체를 사용하고 싶으면
이스케이프 시켜줍니다.
예)
스페이스 \\s
탭 \\t
라인피드 \\n
% 문자 \\%
(3) 그 외
\\d 같은 경우는 [0-9] 와 같습니다. 즉 숫자들에 매치됩니다.
\\w 같은 경우는 [A-Za-z0-9] 와 같습니다.
5. pglex가 매칭하는 원리
- pglex는 텍스트 중심 엔진입니다.
즉 입력 텍스트를 기준으로 처음부터 끝까지 진행하면서
입력한 여러개의 정규식들중 매치된 놈을 선택
그만큼 토큰으로 끊는 과정을 계속 실행하는 겁니다.
5.1 pglex는 여러개의 정규식중에 하나를 선택한다.
- 정규식들은 일종의 후보들인 셈입니다. 그중에서
제일 잘 매치된(?) 놈을 선택합니다.
5.2 pglex는 더 길게 매치된 정규식을 선택한다.
- 두개의 정규식에 매치되었다면 더 길게 매치한 놈을 선택합니다.
예)
%%
int|char|void ;
integer ;
%%
두개의 정규식이 있는데 "integer kkk" 라는 문자열이 들어오면
첫번째 정규식은 "int" 까지 매칭하고 성공합니다.
두번째 정규식은 "integer" 까지 매칭하고 성공합니다.
두번째 정규식이 더 길게 매치되었으므로 두번째 정규식이 선택됩니다.
5.3 pglex는 먼저 쓴 정규식이 더 우선순위를 갖습니다.
- 두개의 정규식에 매치되었는데 매칭된 길이가 같다면
먼저 쓴놈을 선택합니다.
예)
%%
int|char|void puts("type");
[a-z]+ puts("literal");
! puts("!");
%%
main(){pg_lex();}
두개의 정규식이 있는데 "int!!!" 라는 문자열이 들어오면
첫번째 정규식은 "int" 까지 매칭하고 성공합니다.
두번째 정규식도 "int" 까지 매칭하고 성공합니다.
길이가 같지만 먼저 쓴 놈이 선택됩니다.
5.4 아무 정규식에도 매치되지 않으면 에러
&nb
댓글 영역
획득법
① NFT 발행
작성한 게시물을 NFT로 발행하면 일주일 동안 사용할 수 있습니다. (최초 1회)
② NFT 구매
다른 이용자의 NFT를 구매하면 한 달 동안 사용할 수 있습니다. (구매 시마다 갱신)
사용법
디시콘에서지갑연결시 바로 사용 가능합니다.