리플렉스
RE/flex개발자 | 로버트 판 엥겔렌 |
---|---|
안정된 릴리스 | 3.2.2 / 2022년 3월 13일 ( |
저장소 | |
기입처 | C++ |
운영 체제 | 크로스 플랫폼 |
유형 | 어휘 분석 |
면허증. | BSD 라이선스 |
웹 사이트 | https://github.com/Genivia/RE-flex |
급속도로 어휘 분석기를 생성하 RE/flex(regex-centric, 빠르게 낱말 분석기)[1][2]은 무료로 개방된 소스 컴퓨터 프로그램 C++로 쓰여진(또한으로 알려진"스캐너"또는"lexers")[3][4]C++에서. RE/flex 및 성능 opti 조정 완전한 유니 코드 지원, 요면 앵커들, 단어 경계, 게으름을 피우quantifiers(non-greedy, 게으른 재방송)을 제공한다.레드몬드.RE/Flex는 Flex 렉서 사양을 수용하며 Bison 파서용 스캐너를 생성할 수 있는 옵션을 제공합니다.RE/Flex에는 고속 C++ 정규 표현 라이브러리가 포함되어 있습니다.
역사
RE/Flex 프로젝트는 2016년 Robert van Engelen 교수가 설계 및 구현했으며 2017년 무료 오픈 소스로 출시되었습니다.그 소프트웨어는 다른 사람들이 몇 가지 공헌을 하면서 발전했다.RE/Flex 도구는 기존 어휘 분석기 [5]생성기에서 생성된 고정 DFA 테이블 대신 정규 표현("regex") 라이브러리를 기반으로 어휘 분석기를 생성합니다.
렉서 사양
RE/Flex 어휘 분석기 생성기는 Flex 렉서 사양의 확장 구문을 입력으로 받아들입니다.RE/Flex 사양 구문은 기존 Flex 렉서 사양 구문보다 표현력이 뛰어나며 들여쓰기 앵커, 단어 경계, 느린 수량자(비자유, 느린 반복) 및 다음과 같은 새로운 작업을 포함할 수 있습니다.wstr()
Unicode 와이드 스트링의 일치를 취득합니다.
렉서 사양은 다음과 같습니다.
정의 %% 규칙 %% 사용자 코드
[정의(Definitions)]섹션에는 선언 및 커스터마이제이션옵션과 이어서 정규 표현 패턴의 이름을 정의하는 이름 패턴쌍이 있습니다.이름 있는 패턴은 다른 패턴으로 참조할 수 있습니다.{
그리고.}
다음 예시는 2개의 패턴에 2개의 이름을 정의하고 있습니다.여기서 두 번째 패턴은number
는 이전에 이름 붙여진 패턴을 사용합니다.digit
:
%정상{ #실패하다 <int types >h>// strtol() } %학급{ 일반의: 인트 가치; // yyFlexlexer 클래스 공개 멤버 } %초기화{ 가치 = 0; // yyFlexlexer 초기화 } %선택 구부러지다 숫자 [0-9] 번호 {숫자}+
[ Rules ]섹션에서는 패턴과 액션의 페어를 정의합니다.다음 예제에서는 숫자를 렉서 클래스 정수로 변환하는 규칙을 정의합니다.value
멤버:
{번호} 가치 = 스트롯(텍스트, 특수한 순서, 10); \s // 공백 생략 . 던지다 *텍스트;
[사용자 코드(User Code)]섹션에서는 일반적으로 C/C++ 함수를 정의합니다.예를 들어,main
프로그램:
인트 주된() { 플렉서 렉서; 해라 { 하는 동안에 (렉서.플렉스() != 0) 표준::외치다 << > "숫자=" << > 렉서.가치 << > 표준::끝; } 또 만나 (인트 챠) { 표준::cerr << > "오류: 알 수 없는 문자 코드" << > 챠 << > 표준::끝; } }
그yyFlexLexer
클래스는 RE/Flex에 의해 생성됩니다.%option flex
명령어를 참조해 주세요.생성된lex.yy.cpp
소스 코드에는 어휘 분석을 위한 알고리즘이 포함되어 있으며, 이는 다음과 같이 링크되어 있습니다.libreflex
도서관.
소스 코드 출력
생성된 어휘 분석 알고리즘은 입력 토큰화에 원칙적으로 정규 표현 엔진을 사용할 수 있다는 개념을 기반으로 합니다. i , {\ i 의 정규 표현인 n개의 정규 표현 {\displaystyle } 세트가 지정됩니다."() () ... ()"
n개의 교대로 입력과 일치 및 토큰화를 지정할 수 있습니다.이와 같이 정규 표현 매처로부터 반환된 일치 }의 그룹 캡처 인덱스 i는 이전 일치 후 입력 텍스트와 부분적으로 연속적으로 일치한 를 식별한다.
이 방법을 사용하면 그룹 캡처를 지원하는 모든 regex 라이브러리를 매처로서 사용할 수 있습니다.단, 폼의 모든 그룹화는(X)
패턴은 형식의 비패턴 그룹으로 변환되어야 합니다.(?:X)
서브 레퍼런스 내에서 불필요한 그룹 캡처를 회피합니다.
다음 RE/플렉스 생성yyFlexLexer
학급yylex
메서드는 반복적으로 매처의 것을 호출한다.scan
(연속적인 부분 일치) 입력을 토큰화하는 작업:
인트 yyFlexlexer::yylex() { 한다면 (!has_matcher()) 마처((p1) (p2) ... (pn)); // regex 패턴(p1) (p2) ... (pn)의 새로운 매처 엔진 하는 동안에 (진실의) { 전환하다 (마처().스캔()) // 다음 토큰을 검색하여 일치시키고 캡처 인덱스를 가져옵니다. { 사례. 0: // 일치 없음 한다면 (... EOF 도달된 ...) 돌아가다 0; 산출량(마처().입력()); // 현재 입력 문자를 에코합니다. 브레이크.; 사례. 1: // 패턴 p1 일치 ... // 패턴 p1에 대한 액션 브레이크.; 사례. 2: // 패턴 p2 일치 ... // 패턴 p2에 대한 액션 브레이크.; ... // 최대 pn 패턴에 대해서도 마찬가지입니다. } } }
n개의 패턴 중 어느 것도 일치하지 않고 End-of-File(EOF; 파일 종료)에 도달하지 않으면 이른바 "기본 규칙"이 호출됩니다.기본 규칙 반향은 현재 입력 문자이며 스캐너를 입력의 다음 문자로 이동합니다.
정규 표현 패턴"() () ... ()"
패턴-액션 쌍의 n개의 규칙을 가진 렉서 규격에서 RE/flex에 의해 생성된다.
%% p1 패턴 p2 동작 패턴 p2 ... pn 패턴 pn %% 동작
이 사양에서 RE/flex는 앞서 언급한 사항을 생성합니다.yyFlexLexer
와의 클래스yylex()
입력에서 일치하는 패턴에 대응하는 액션을 실행하는 메서드.생성된yyFlexLexer
class는 파서 등의 C++ 어플리케이션에서 사용되며 입력이 렉서 사양의 액션에 의해 반환되는 정수값 토큰으로 토큰화됩니다.예를 들어 다음과 같습니다.
표준::ifstream ifs(파일명, 표준::IOS::에); 플렉서 렉서(ifs); 인트 상품권; 하는 동안에 ((상품권 = 렉서.플렉스()) != 0) 표준::외치다 << > "오디오 =" << > 상품권 << > 표준::끝; ifs.가까운.();
주의:yylex()
액션이 실행될 때 정수 값을 반환합니다.return token_value;
.그렇지않으면,yylex()
는 값을 반환하지 않고 입력 스캔을 계속합니다.이것은, 코멘트등의 입력을 무시하는 룰에 의해서 자주 사용됩니다.
다음 예제에서는 파일을 토큰화합니다.어휘 분석기는 종종 Bison과 같은 파서 생성기에 의해 생성된 파서의 토큰라이저 역할을 합니다.
호환성.
RE/Flex는 다음과 같은 Flex 사양과 호환됩니다.%option flex
사용됩니다.이것에 의해, 다음과 같이 생성된다.yyFlexLexer
와 같은 반을 나누다.yylex()
방법.또한 RE/Flex는 다양한 RE/Flex 옵션을 사용하여 Bison과 호환되며, Bison의 옵션과 기능을 모두 지원합니다.
Flex 와는 대조적으로 RE/Flex 스캐너는 재진입 Bison 파서를 사용하는 경우 기본적으로 스레드 세이프입니다.
Unicode 지원
RE/Flex 는, 렉서 사양으로 Unicode 정규 표현 패턴을 서포트해, UTF-8, UTF-16, 및 UTF-32 입력 파일을 자동적으로 토큰화합니다.ISO/IEC 8859 1~16, Windows-1250에서 Windows-1258, CP-437, CP-850, CP-858, MacRoman, KOI-8, EBCDIC 등으로 인코딩된 입력 파일을 토큰화하도록 코드 페이지를 지정할 수 있습니다.UTF-8로의 정규화는 Unicode 정규 표현 패턴과의 (부분적인) 패턴 조회를 위한 내부 증분 버퍼링에 의해 자동으로 실행됩니다.
들여쓰기, 결절 및 전용 매칭
RE/Flex는 들여쓰기 및 전용 매칭을 새로운 정규 표현 구문과 직접 통합합니다.\i
그리고.\j
닻을 올립니다.이러한 들여쓰기 앵커는 입력에서 줄 들여쓰기의 변화를 감지합니다.이를 통해 블록 구조가 들여쓰기된 프로그래밍 언어를 토큰화하기 위해 많은 실제 시나리오를 다룰 수 있습니다.예를 들어, 다음 렉서 사양은 들여쓰기 변경을 검출하여 보고합니다.
%% ^[ \t]+ 표준::외치다 << > " "; // 결절: 텍스트가 현재 들여쓰기 여백에 정렬됩니다. ^[ \t]*\i 표준::외치다 << > ">"; // 들여쓰기: \i와 일치합니다. ^[ \t]*\j 표준::외치다 << > "< "; // 전용: \j와 일치 \j 표준::외치다 << > "< "; // 전용: 각 추가 레벨 전용 %%
지연 수량화
느린 수량화자는 RE/플렉스 정규 표현 패턴의 반복과 관련지어 필요에 따라 비-권한 반복을 사용하여 표현을 단순화할 수 있습니다.일반적으로 매칭은 "greedy"이며, 이는 가장 긴 패턴이 매칭됨을 의미합니다.예를 들어 패턴은a.*b
욕심쟁이들과 함께*
시합을 반복하다aab
일치시키기도 합니다.abab
왜냐면.*
줄 바꿈과 줄 바꿈을 제외한 모든 문자와 일치합니다.abab
보다 길다ab
. lazy 정량자 사용?
게으른 반복을 위해*?
,양식a.*?b
일치하다ab
하지만 아니다abab
.
느린 수량화자의 실용적인 적용으로 C/C++ 형식의 여러 줄 코멘트를 일치시키는 것을 고려하십시오./*...*/
. 렉서 사양 패턴"/*"(. \n)*?"*/"
느릿느릿 반복하여*?
는 여러 줄의 코멘트와 일치합니다.게으름 피우지 않고 패턴을 반복하다"/*"([^*] (\*+[^*/]))*\*+"/"
사용되어야 한다(양식의 인용문)."..."
렉서 사양에서만 허용되며, 이 구성은 Rexer 사양과 유사합니다.\Q...\E
대부분의 regex 라이브러리에서 지원되는 인용문)
성능
RE/flex는 정규 표현 패턴 매처(RE/flex regex 및 Boost)를 선택할 수 있습니다.Regex. RE/Flex regex 엔진은 DFA를 으로 하며 일반적으로 입력 길이 n에서 O() \ O ( )。부스트Regex는 보다 풍부한 정규 표현 패턴 구문을 제공하지만 NFA 기반 일치 알고리즘 때문에 속도가 느립니다.
기본적으로는 RE/flex는 DFA 테이블을 생성하여 매처 속도를 높입니다.scan
작동.패턴 매칭을 위한 보다 빠른 DFA가 생성됩니다.--fast
선택.이 DFA는 표가 아닌 직접 코드로 표현됩니다.예를 들어, 패턴에 대해 다음과 같이 코드화된 DFA가 있습니다.\w+
는 단어와 일치하도록 매우 효율적으로 실행됩니다.
무효 리플렉스_코드_FSM(반사.::매처& m) { 인트 c1; m.FSM_INIT(c1); S0: c1 = m.FSM_CHAR(); 한다면 (97 <=> c1 & & c1 <=> 122) 에 가다 S5; 한다면 (c1 == 95) 에 가다 S5; 한다면 (65 <=> c1 & & c1 <=> 90) 에 가다 S5; 한다면 (48 <=> c1 & & c1 <=> 57) 에 가다 S5; 돌아가다 m.FSM_HALT(c1); S5: m.FSM_TAKE(1); c1 = m.FSM_CHAR(); 한다면 (97 <=> c1 & & c1 <=> 122) 에 가다 S5; 한다면 (c1 == 95) 에 가다 S5; 한다면 (65 <=> c1 & & c1 <=> 90) 에 가다 S5; 한다면 (48 <=> c1 & & c1 <=> 57) 에 가다 S5; 돌아가다 m.FSM_HALT(c1); }
퍼포먼스는 RE/Flex 내장 프로파일러를 사용하여 최적화를 위해 분석할 수 있습니다.프로파일러는 생성된 소스 코드를 계측합니다.스캐너가 종료되면 프로파일러는 규칙이 일치한 횟수와 일치 규칙에 의해 소비된 누적 시간을 보고합니다.프로파일링에는 규칙이 파서에 제어를 반환할 때 파서에서 보내는 시간이 포함됩니다.이를 통해 생성된 스캐너와 파서의 성능을 미세 조정할 수 있습니다.우선, 핫 스팟인 렉서 규칙, 즉 계산 비용이 많이 드는 렉서 규칙을 검출한다.그런 다음 효과적인 최적화는 이러한 고가의 규칙과 파서의 최적화에 초점을 맞춰야 합니다.
「 」를 참조해 주세요.
레퍼런스
- ^ van Engelen, Robert (April 15, 2017). "Constructing Fast Lexical Analyzers with RE/flex - Why Another Scanner Generator?". CodeProject.
- ^ Heng, Christopher (December 27, 2018). "Free Compiler Construction Tools".
- ^ Levine, John R.; Mason, Tony; Brown, Doug (1992). lex & yacc (2nd ed.). O'Reilly. pp. 1–2. ISBN 1-56592-000-7.
- ^ Levine, John (August 2009). flex & bison. O'Reilly Media. p. 304. ISBN 978-0-596-15597-1.
- ^ Aho, Alfred; Sethi, Ravi; Ullman, Jeffrey (1986). Compilers: Principles, Techniques and Tools. Addison-Wesley.