2013-12-15 3 views
0

다음과 같은 형식의 코드가 있습니다.일부 flex/bison 질문

display <<"hello">> (number1) (number2) (number3) { 
    a = 1; 
    b = 2; 
    ... 
} 

참고이 못생긴 예이기는하지만, 단지 예이지만, 여전히, 그것은 내가하고 싶은 것의 단지 exageration입니다. number1, number2, number3은 숫자이고 display는 변수 할당을 포함하는 {} 사이의 블록과 특수한 방식으로 전체를 인쇄하는 연산자의 일종입니다. 말했듯이, 단지 예입니다.

이 질문에 대한 나의 질문은 ... display <<str>>()()() {} 양식은 "display"키워드와 함께 사용되며 이후에는 사용되지 않습니다. < < 및 >> 연산자는 일반적으로 연산자라고 가정합니다. 궁금한 점이 있다면 ... bison/flex에게이 경우 < < 및 >> 연산자는 사용되지 않고 "표시"구문에 속한 구분 기호 만 사용할 수 있습니까? 그리고 어떻게 < <과 >> 사이의 데이터를 올바르게 추출 할 수 있습니까?() 사이의 숫자는 {} 사이의 블록에 다른 구문을 사용하여 전체 블록을 구문 분석합니까? 예를 들어

나는이 있다면 :

display <<"hello">> (1) (5) (8) { 
    a = 1; 
    b = 8 * 273 + 40; 
} 

내가의 호출과 같이하고 싶습니다 :

handle_display_operator(szStr, num1, num2, num3) 

// here szStr contains "hello", num1 = 1, num2 = 5, num3 = 8 

이 함수 호출 후,이 블록으로 분석 할 필요가있다.

누군가 내가이 문제를 어떻게 적절하게 처리 할 수 ​​있는지 설명 할 수 있습니까? 당신이 좋아하는 들소 규칙으로이 쓸 수

감사

답변

1

: 렉서가 토큰 LSHIFT 및 RSHIFT 같은 키워드 DISPLAY로 display<<>>을 인식

statement: DISPLAY LSHIFT string RSHIFT '(' expr ')' '(' expr ')' '(' expr ')' 
       { handle_display_operator($3, $6, $9, $12); } 
      block 
     ; 

. 다른 컨텍스트 (예 : 표현식)에서는 시프트 연산자로 LSHIFTRSHIFT을 사용합니다.

괄호 안의 ANY 표현식 (expr 규칙의 정수로 평가할 수 있음)을 허용하고 string 규칙에서 문자열 '표현식'을 처리 할 수 ​​있습니다.

대체 방법으로 <</>> (문자열이 아닌) 사이의 원시 텍스트를 사용하려는 경우 display 키워드 뒤에 flex exclusive state를 사용하는 것이 좋습니다.

statement: DISPLAY RAW_TEXT '(' expr ')' '(' expr ')' '(' expr ')' 
       { handle_display_operator($2, $4, $7, $10); } 
      block 

display << %" ,> >> (1)(2)(3)처럼 입력을 허용하고 핸들 기능 %" ,> (선행/후행 공백을 포함한 문자열을 전달합니다

%x display, raw_text 
%{ 
    /* use a dynamic buffer if you don't have an upper limit on the length */ 
    static char raw_text_buffer[MAX_LENGTH], *raw_text_end; 
%} 

%% 

"display"  { BEGIN(display); return DISPLAY; } 
<display>"<<" { BEGIN(raw_text); raw_text_end = raw_text_buffer; } 
<raw_text>. { *raw_text_end++ = *yytext; /* DANGER -- may overflow */ } 
<raw_text>\n { error?? or just put it in the buffer... } 
<raw_text>">>" { *raw_text_end = 0; 
       yylval.string = strdup(raw_text_buffer); 
       BEGIN(INITIAL); 
       return RAW_TEXT; } 

지금 당신의 규칙은 다음과 같이 표시됩니다 그럼 당신은 같은 플렉스 규칙이있을 것이다 , 인용 및 모든. 물론

, 당신은 적절한 오류 메시지와 버퍼 오버 플로우에 대한 검사를 추가해야합니다. comprehe에 대한

+0

감사합니다 대답하고 빨리 대답 해.나는 아직도 한 가지 점에 관해서 당신의 경험으로부터 이익을 얻고 싶습니다. 디스플레이가 처리하는 블록에서, 내부에 고유 한 구문을 갖고 싶습니다. 예를 들어 struct {block}과 같은 블록을 받아들이는 'struct'라는 두 번째 연산자가 있고 구조체 구문 내부의 블록에도 내부적으로 고유 한 구문이 있다고 가정 해보십시오. 다시 한 번 예를 외치기는하지만이 개념을 분명히 이해하고 싶습니다. 나는 또 다른 yyparse() (접두어 붙이기)를 만들어야 할까, 아니면 하나의 파서로 할 수 있을까? 감사! – Yannick