2014-12-04 6 views
2

내 문법 수 있습니다 :플렉스/렉스 - 어떻게 변수가 선언 알고

C의 → 아이디 : = E // 지정 값/변수 표현 (VAR)

C → 인쇄 (ID) // 인쇄 변수 (VAR)이 그것을 수행하려면

값, 내 렉스 파일은 다음과 같습니다

목록에서 변수의 인덱스를 반환 get_var_index
[a-z]{ 
    yylval.var_index=get_var_index(yytext); 
    return VAR; 
} 

, 그것이 생성 한 후 존재하지 않는 경우 하나. 작동 중!

문제는 다음

  • 매번 변수는 그 변수에 대한 색인을 작성하는 파일 렉스에 일치한다.
  • 나는 '인쇄의 (a)' '는이'선언되지 않은 전화를하는 경우보고해야하고, 인쇄 (a)는 항상 'A'에 인덱스를 생성하기 때문에 그런 일이 없을 것. *

어떻게 해결할 수 있습니까? Yacc에 파일의

조각 :

%union { 
int  int_val; 
int var_index; 
} 
%token <int_val> INTEGER 
%token <var_index> VAR 
... 
| PRINT '(' VAR ')'{ 
n_lines++; 
printf("%d\n",values[$3]); 
} 
... 
| VAR {$$ =values[$1];} 

답변

1

이 우리가 할 수의 컴퓨터 과학 수업 숙제 질문처럼 조금 보인다.

일반적으로 이러한 방법으로 bison/yacc를 사용하지 않습니다. bison/yacc을 사용하여 구문 분석을 수행하고 구문 트리를 작성한 다음 구문 분석 트리를 만들어 사용 전에 선언 확인과 같은 의미 검사를 수행합니다. 일반적으로 식별자는 과 같이 다른 속성을 활성화하는 데 사용되는 값 표 대신 심볼 표로 관리되어으로 관리됩니다. 이러한 이유 때문에 도구의 실제 적용보다는 운동처럼 보입니다. 승인; 그 면책 조항은 답변을 얻을 수 있습니다.

문제는 선언 된 내용과 그렇지 않은 내용을 기억하면 해결됩니다. 전체 기호 테이블을 사용하지 않으려는 경우 유효한 값을 나타내는 부울 값의 간단한 배열을 사용할 수 있습니다. 배열은 거짓으로 초기화되고 true로 선언 될 때으로 설정할 수 있습니다. 이 값은 변수가 사용될 때 검사 할 수 있습니다. C부울에 대해 int를 사용합니다. 필요한 변경 사항은 bison/yacc에만 있습니다. 선언에 대한 구문을 생략했지만 선언 한대로 일부 구문이 있어야합니다. 나는 짐작했다.

%union { 
int  int_val; 
int var_index; 
} 
int [MAX_TABLE_SIZE] declared; /* initialize to zero before starting parse */ 
%token <int_val> INTEGER 
%token <var_index> VAR 
... 
| DECLARE '(' VAR ')' { n_lines++; declared[$3] = 1; } 
... 
| PRINT '(' VAR ')'{ 
n_lines++; 
if (declared[$3]) printf("%d\n",values[$3]); 
else printf("Variable undeclared\n"); 
} 
... 
| VAR {$$ =value[$1]; /* perhaps need to show more syntax to show how VAR used */}