2017-11-30 34 views
1

나는이플렉스 스캔 및 패딩 (단일 공백) 문자열 구별 (하나 개 이상의 공간)

DESCRIPTION     This is the device description 

같은 것을 보이는 라인을 스캔 플렉스에 문제가 있어요 내가 할 줄을 싶습니다 그런 설명은 하나의 토큰이며 "이것은 장치 설명입니다"입니다.

나는 내 규칙에 끝없이 놀고 있지만 제대로 작동하지 않는 것 같습니다. 내가

`R/S ' 에 R하지만를 사용하여 규칙을 구현하려는 생각 문서에서

그것은 공간 만 허용됩니다에 S

다음 경우에만 그들은 공간이 아닌 무언가가 뒤 따른다. flex의 구문을 사용하여이 규칙을 작성하는 방법을 모른다. 내 마음 속에서 규칙은 다음과 같아야합니다.

[a-zA-Z](" "/[a-zA-Z0-9]|[a-zA-Z0-9])*  return IDENTIFIER; 

그러나 이것은 유효하지 않습니다.

각 단어를 잘라내는 줄을 얻을 수는 있지만 1 개의 공백과 1 개의 < 공백을 구별하는 규칙을 얻을 수 없습니다. 하프.

답변

0

토큰 인식이 컨텍스트에 따라 다르기 때문에 이것은 실제로 flex와 잘 맞지 않습니다. start conditions을 사용하여 컨텍스트 종속 검색을 수행 할 수 있지만 시작 조건을 과도하게 사용하면 다른 검색 메커니즘이 더 좋음을 나타내는 경우가 많습니다.

어떻게 수행하든 관계없이 키는 정확히 토큰 분할을 결정하는 방법을 알아 냈습니다. 예를 들어, 다음과 같은 네 가지 라인을 고려 : 물론

DEVICE  This is the device 
MODE  This is the mode 
DESCRIPTION This is the device description 
UNDOCUMENTED FIELD 

, 세 번째와 네 번째 라인으로 표시 코너의 경우이 입력의에 표시하지 않을 가능성이 있습니다.

첫 번째 토큰은 공백을 포함 할 수없는 경우, 다음 문제는 아직 시작 조건이 필요하지만 (내가 생각하는거야 당신은 위의 링크 된 문서 읽기), 비교적 간단하다 :

%x WHITE WORDS 
%% 
    /* Possibly should be [[:alpha:]] instead of [[:upper:]] */ 
[[:upper:]]+ { /* copy yytext */; BEGIN(WHITE); return KEYWORD; } 
    /* Handle other possible line beginnings */ 
<WHITE>\n  { /* Blank descriptive text */; BEGIN(INITIAL); } 
<WHITE>[ \t]+ { BEGIN(WORDS); } 
<WHITE>.  { /* Something not correct in this line */; ... } 
<WORDS>.+  { /* copy yytext */; BEGIN(INITIAL); return DESCRIPTION; } 
<WORDS>\n  { BEGIN(INITIAL); } 

하는 경우를 정확히 하나가있는 곳에

[[:alpha:]]+([[:alpha:]]+)* 

는 (문자 만 구성된) 단어의 순서와 일치하는 것이다 :이 첫 번째 토큰에 공백이 될 수 있지만 연속 결코 두 공간, 당신과 함께 위의 첫 번째 패턴을 대체 할 수 연속적인 wor 사이의 공간 ds. 위의 원래 패턴과 마찬가지로, 발견 된 첫 번째 비 알파벳 문자로 끝납니다. 이 오류는 <WHITE>에있는 규칙에 의해 감지됩니다. 시작 조건이 활성화 될 때 비어있는 공백 문자가 발생하면 시작 조건의 기본 규칙 (<WHITE>. 규칙)에 의해 처리되기 때문입니다.

+0

이것은 C 프로그래밍 언어의 문제가 아니므로 – user3629249

+0

@ user3629249의 'c'태그를 제거하십시오. 나는 현재 내가 갖고있는 질문을 편집 할 수 있습니다. OP가 그것을 편집하기를 원한다면 질문에 대해 언급해야합니다. 내 대답이 아니야. 나는 C 태그가 틀렸다는 것을 완전히 확신하지는 못했다. 더 많은 시간을 투자 했더니 플렉스가 생성 한 C 솔루션뿐만 아니라 C 솔루션을 제안했을 것입니다. 하지만 그것은 당신과 포스터 사이에 ... – rici

+0

큰 큰 감사합니다 @rici. 지금 당장 말이야! –

0

내 의견은 여기에 잘못된 말을 사용하고 있다는 것입니다. lex (flex)는 어휘 분석에만 사용되고 yacc (또는 bison)은 구문 적 해석에만 사용되어야합니다.하나의 문자가 구분 기호가 아니고 여러 문자가 렉서에 적절하지 않다고 해보자.

제 의견으로는 렉스는 단어와 패딩 만보고하고 나중에 yacc는 패딩 요소로 구분되지 않은 단어를 다시 조합해야한다는 것입니다.

렉스 부분은 간단 할 것 :

[[:alnum:]_]+ { 
     // printf("WORD: >%s<\n", yytext); // for debugging 
     return WORD; 
    } 

[[:blank:]]{2,} { 
     // printf("PADDING: >%s<\n", yytext); 
     return PADDING; 
    } 

와 yacc은 부분이 포함됩니다 : 그들은 당신의 실제 처리에 너무 많이 의존하기 때문에

elt: PADDING 
    | ident 

ident: WORD 
    | ident WORD 

작업이 생략된다.

+0

당신의 도움에 감사드립니다. 나는 아마도 전반적으로이 문제에 대해 가난한 방법으로 접근했다. 하지만 yacc에 익숙해지기 시작하면 yacc에 익숙해지고 나면 여러분의 방법이 더 좋아 보일 것이라고 확신합니다. 감사! @sergeballesta –