리플렉스

RE/flex
리플렉스
개발자로버트 판 엥겔렌
안정된 릴리스
3.2.2 / 2022년 3월 13일 (2022-03-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()입력에서 일치하는 패턴에 대응하는 액션을 실행하는 메서드.생성된yyFlexLexerclass는 파서 등의 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 내장 프로파일러를 사용하여 최적화를 위해 분석할 수 있습니다.프로파일러는 생성된 소스 코드를 계측합니다.스캐너가 종료되면 프로파일러는 규칙이 일치한 횟수와 일치 규칙에 의해 소비된 누적 시간을 보고합니다.프로파일링에는 규칙이 파서에 제어를 반환할 때 파서에서 보내는 시간이 포함됩니다.이를 통해 생성된 스캐너와 파서의 성능을 미세 조정할 수 있습니다.우선, 핫 스팟인 렉서 규칙, 즉 계산 비용이 많이 드는 렉서 규칙을 검출한다.그런 다음 효과적인 최적화는 이러한 고가의 규칙과 파서의 최적화에 초점을 맞춰야 합니다.

「 」를 참조해 주세요.

레퍼런스

  1. ^ van Engelen, Robert (April 15, 2017). "Constructing Fast Lexical Analyzers with RE/flex - Why Another Scanner Generator?". CodeProject.
  2. ^ Heng, Christopher (December 27, 2018). "Free Compiler Construction Tools".
  3. ^ Levine, John R.; Mason, Tony; Brown, Doug (1992). lex & yacc (2nd ed.). O'Reilly. pp. 1–2. ISBN 1-56592-000-7.
  4. ^ Levine, John (August 2009). flex & bison. O'Reilly Media. p. 304. ISBN 978-0-596-15597-1.
  5. ^ Aho, Alfred; Sethi, Ravi; Ullman, Jeffrey (1986). Compilers: Principles, Techniques and Tools. Addison-Wesley.

외부 링크