2013-03-28 4 views
0

저는 며칠 동안이 문제에 의문을 제기 해 왔으며 검색 결과에 아무런 영향을주지 않는 것으로 보입니다. 가능한지 궁금합니다. 예를 들어JavaCC에서 입력을 '토큰'으로 사용합니다.

funct functionNAME (Object o) { o+1 }; 

포인트는 사용자 식별자 중괄호 내에서 'O'가 아닌 다른 식별자를 사용한다는 것이다. 이것은 물론 'o'가 될 수있는 (Object o) 부분의 입력에 의해 지정됩니다. 기본적으로 중괄호 안에있는 식별자는 매개 변수에 정의 된 식별자와 동일해야합니다. 일치하는 토큰을 저장하고 화면에 출력 할 수 있지만 어휘 토큰으로 사용할 수 있습니까? 감사.

+0

Reflection에 대해 묻고 싶습니까? http://stackoverflow.com/questions/37628/what-is-reflection-and-why-is-it-useful – Aboutblank

+0

JavaCC를 사용하여 컴파일러를 작성하는 경우 수행하려는 작업은 추적을 유지하는 기호 테이블을 유지하는 것입니다 어떤 식별자가 코드의 각 지점에서 사용될 수 있는지. 기호 표는 일반적으로 식별자에 대한 유용한 정보 (예 : 변수 대 함수)와 유형에 대한 정보도 보관합니다. –

+0

질문을 명확히 할 수 있습니까? 마지막 문장에서 알 수있는 것은 "일치하는 토큰을 어휘 토큰으로 사용할 수 있습니까?"입니다. 하지만 그건 네가 의미하는 바가 아닌 것 같아. –

답변

2

예 이렇게하는 것이 더 좋습니다. 기호 테이블이 필요합니다. 기호 표의 작업은 프로그램의 각 지점에서 사용할 수있는 식별자를 추적하는 것입니다. 일반적으로 기호 테이블에는 식별자에 대한 다른 정보 (예 : 변수 또는 함수 이름)와 유형에 대한 정보가 포함됩니다.

기호 테이블을 사용하면 구문 분석 중에 범위를 벗어나는 변수의 사용을 감지 할 수 있습니다. 예 : C와 Pascal은 식별자를 사용하기 전에 식별자를 선언해야하는 언어입니다 (예외는 일부 있음). 그러나 다른 언어 (예 : Java)는 식별자가 사용 된 후에 선언 할 수있게하며,이 경우 프로그램을 구문 분석 할 때까지 선언되지 않은 변수를 사용하는 등의 오류를 감지하지 않는 것이 가장 좋습니다. (실제로 Java에서는 식별자가 다른 파일에서 선언 될 수 있기 때문에 모든 파일이 구문 분석 될 때까지 기다려야합니다.)

변수에 대한 정보 만 기록하면되는 간단한 시나리오를 가정합니다. 타입 정보가 아니며 사용하기 전에 반드시 선언해야합니다. 그렇게하면 시작할 수 있습니다. 필자는 심볼 테이블에 함수 이름을 추가하는 것에 대해 신경 쓰지 않았습니다.

심볼 테이블이 프레임이라고하는 스택이라고 가정합니다. 각 프레임은 변경 가능한 문자열 세트입니다. (나중에 문자열에서 변경된 추가 정보로 변경할 수도 있습니다.)

void Start(): { } 
{ 
    <FUNCTION> 
    <IDENTIFIER> 
    {symttab.pushNewFrame() ;} 
    <LBRACKET> Parameters() <RBRACKET> 
    <LBRACE> Expression() <RBRACE> 
    {symtab.popFrame() ; } 
} 
void Parameters() : {} 
{ 
    (Parameter() (<COMMA> Parameter())*)? 
} 
void Parameter() : { Token x ; } 
    <OBJECT> x=<IDENTIFIER> 
    { if(symtab.topFrame().contains(x.image)) reportError(...) ; } 
    { symtab.topFrame().add(x.image) ; } 
} 
void Expression() : { } 
{ 
    Exp1() (<PLUS> Exp1())* 
} 
void Exp1() : { Token y ; } 
{ 
    y = <IDENTIFIER> 
    { if(! symtab.topFrame().contains(y.image)) reportError(...) ; } 
| 
    <NUMBER> 
} 
+0

스택이 가장 좋은 방법입니까? –

+0

이것은 컴파일러/언어 프로세서의 특성에 따라 다릅니다. 원 패스 컴파일러의 경우 범위를 벗어난 심볼에 액세스 할 필요가 없습니다. 이 경우 프레임 스택이 의미가 있습니다. 예를 들어, 각 서브 루틴의 끝에서 매개 변수가 더 이상 필요하지 않으므로 기호 테이블 스택에서 맨 위 프레임을 팝핑 할 수 있습니다. 멀티 패스 컴파일러의 경우 향후 패스에서 심볼 테이블이 필요할 것이므로 심볼 테이블 프레임을 트리 구조로 유지하는 것이 더 적합합니다. –

0

일치 항목 식별자 o의 값을 저장할 수 있으며 중괄호에 동일한 식별자가 있는지 확인하고 그렇지 않은 경우 예외를 throw 할 수 있습니다.

+0

네, 그게 가능하다는 것을 알고 있습니다.하지만 그걸로 내가 얻은 것입니다. 나는 그것을 '토큰'으로 사용하는 방법을 알아낼 수 없다. 무효 showO() : 예를 들어 {} { o.image } 그 코드가 작동하지 않습니다 알고 있지만 나는 그런 일을 찾고 있어요. –

0

좋아, 내가 OP에서 준 예제를 기반으로 원하는 것을 얻는 방법을 찾았습니다. 그것은 단지 내가 개념 증명을하기 위해 구현 한 솔루션의 단순한 변형입니다. 단순화를 위해 토큰 정의와 같은 사소한 것들을 생략 할 것입니다.

void Start(): 
{ 
    Token x, y; 
} 
{ 
    <FUNCTION> 
    <FUNCTION_NAME> 
    <LBRACKET> 
    <OBJECT> 
    x = <PARAMETER> 
    <RBRACKET> 
    <LBRACE> 
    y = <PARAMETER> 
    { 
     if (x.image.equals(y.image) == false) 
     { 
      System.out.println("Identifier must be specified in the parameters."); 
      System.exit(0); 
     } 
    } 
    <PLUS> 
    <DIGIT> 
    <RBRACE> 
    <COLON> 
} 

더 좋은 방법이 있나요?