기호 테이블 후 인구 분석;컴파일러 건설
-
13-12-2019 - |
문제
후을 만드는 구문 분석,나무 나이를 채우는 기호 테이블에 지금이다.
나과 같은 정보를 저장
유형,범위,상쇄 등에 대한 식별자입니다.
지금 어떻게 알 수 있는 형식의 범위를 식별자 때문에,내가 아는 모든 것입니 lexeme 의 가치와 선수정 ID(후 어휘 분석).
어떻게 내가에 대한 전체적인 것입니다.감사합니다.
해결책
지금 어떻게 알 수 있는 형식의 범위를 식별자,이후 모든 나 알아 lexeme 의 가치와 선수정 ID(후 어휘 분석).
로 EJP 언급된,필요를 통해 단계별로 구문 분석 트리입니다.당신의 나무가 있어야 만들 수 있도록 수행하기 위해 탐색,방문하는 각 노드에 동기 위해서는 소스 코드를 문와 표현을 평가합니다.귀하의 노드 트리도에 해당하는 특정 언어를 구성,예를 들어, WhileStmtNode
, MethodDeclNode
, 니다,등등.
가정 내가 건축 기호 테이블,재귀적으로 스테핑을 통해 나무,그리고 나는 단지 입력 방법은 신체 노드입니다.수은 다음과 같습니다.
public void doAction(MethodBodyNode methodBody) {
currScope = 2;
methodBody.getExpr().applyAction(this);
currScope = 2;
}
저는 계속 변수를 관리하는 범위입니다.시간 블럭을 입력 범위 변화,내가 증가 currScope
.마찬가지로,나는 유지 currClass
고 currMethod
변수를 저장하는 상징과 이름을 입력,오프셋,etc.을 위한 늦게 단계로 구성됩니다.
업데이트:
지금도 이르기를 나는 순회하는 나무마다 이 ID 나 를 입력 값을 기호 테이블과 함께 유형 범위와 다른 사람,말에 대한 범위를 확인하는 경우에'{'나 함수 이름이지만,나는 어떻게 어떤 유형의 ID 은 이것입니다.
각 노드 트리를 포함해야를 위해 필요한 모든 정보는 전체를 구성.를 사용하는 경우에는 파서 생성기처럼,컵 또는 들소,지정할 수 있는 방법을 구축하는 나무에 문법 작업입니다.E.g.
variableDeclaration::= identifier:i identifier:i2 SEMICOLON {: RESULT = new VarDeclNode(i, i2, null); :};
identifier::= ID:i {: RESULT = new IdNode(i.getLineNum(), i.getCharNum(), i.getStringValue()); :};
그 productions 치 Foo f;
추가 변수 선언 노드 트리입니다.는 노드를 캡슐화하는 두 가지 식별자가 포함된 노드 라인 번호,문자로 숫자 및 문자열 값의 lexeme 의.첫 번째 식별자 노드의 종류와 두 번째는 변수 이름을 지정합니다. ID
터미널 기호에 의해 반환되는 아키텍처 독립적인에 일치하는 식별자입니다.나는 당신이 어느 정도.
public class VarDeclNode extends StmtNode {
private IdNode id;
private IdNode type;
private ExprNode expr;
public VarDeclNode(IdNode id, IdNode type, ExprNode expr) {
super();
this.id = id;
this.type = type;
this.expr = expr;
}
}
가지고 있을 때는 구문으로 나무 노드의 다음과 같이,당신이하는 모든 정보를 확인할 수 있습니다.
2 업데이트:
그것이 문제가되지 않를 사용하고 있는지 여부 사용자 정의 파서 또는 생성되어 중 하나,거기에 하나의 고유한 포인트는 노드를 추가로 나무에 일치하는 생산입니다.그것은 중요하지 않습니다 어떤 언어를 사용합니다.C 구조체를 잘 할 것입니다.
는 경우 그것은 터미널 정보로 Nonterminals 이름을 경우 터미널 즉토큰,다음의 정보 즉,토큰lexeme 의 값이 토큰의 이름과 줄 수 있는 저장
어야 합니다 전문화된 노드 트리에서,예를 들어,ClassNode,TypeNode,MethodDeclNode,IfStmtNode,ExprNode.할 수 없습니다 단지 저장 형식의 노드를 넣어 비 터미널 및 터미널에서습니다.비 터미널로 표시된 노드 트리가 다른 정보를 저장하는 그것에 대해 옆에 있는 부분을 구성하는 그것은,일반적으로 비 터미널다.지 않을 저장하는 모든 토큰의 정보입니다.가 있지만 몇 가지는 경우 실제로 저장 한 lexeme 의 문자열 값:에 대한 식별자와 문자열//정수값다.
보 이 예입니다.하는 동안 첫 번째 감소 S
은 감소 (S + F)
, 에,당신은 추가 ParenExprNode
트리 루트입니다.당신은 또한 추가 AddExprNode
로 아동의 ParenExprNode
.는 논리해야 하드 코딩의 파서를 신청할 때는 감소에 의한 규칙 2 의 문법입니다.
트리:
ExprNode (root)
|
ParenExprNode
|
AddExprNode
/ \
ExprNode ExprNode
코드:
struct ExprNode { void* exprNode; };
struct ParenExprNode { void* exprNode; };
struct AddExprNode { void* op1, * op2; };
struct IdNode { char* val; int line; int charNum; };
struct IntLiteralNode { int val; int line; int charNum; };
void reduce_rule_2(ExprNode* expr) {
//remove stack symbols
//create nodes
struct ParenExprNode* parenExpr = malloc(sizeof(struct ParenExprNode));
struct AddExprNode* addExpr = malloc(sizeof(struct AddExprNode));
addExpr->op1 = malloc(sizeof(struct ExprNode));
addExpr->op2 = malloc(sizeof(struct ExprNode));
//link them
parenExpr->exprNode = (void*)addExpr;
expr->exprNode = (void*)parenExpr;
}
다음 단계에서 왼쪽에 괄호 안에서 제거 입력이 있습니다.후에, S
최고의 스 감소 F
으로 규칙 1.이 F
비 터미널에 대한 식별자는,그것으로 표시 IdNode
.
트리:
ExprNode
|
ParenExprNode
|
AddExprNode
/ \
ExprNode ExprNode
|
IdNode
코드:
reduce_rule_2(addExpr->op1);
void reduce_rule_1(ExprNode* expr) {
//reduce stack symbols
struct IdNode* id = malloc(sizeof(struct IdNode));
id->val = parser_matched_text();
id->lineNum = parser_line_num();
id->charNum = parser_char_num();
expr->exprNode = (void*)id;
}
그래서...
다른 팁
알고있는 모든 것은 해당 ID
의 lexeme 값과 줄 번호입니다
사실이 아닙니다.당신은 당신이 필요로하는 모든 것을 알려주는 구문 분석 나무에서 어디에서 선언 된 곳을 알고 있습니다.당신은이 단계를 처리 파스 트리를 수행합니다.