2011-12-16 2 views
6

У нас есть назначение сделать компилятор. Мы уже сделали лексический и синтаксический анализ, но мы застряли в генерации промежуточного кода. Мы поняли, что нам нужно реализовать таблицу символов, чтобы перейти к созданию промежуточного кода, и мы не знаем, как это сделать и что он содержит.Как создать таблицу символов

Учитывая приведенный ниже код, что должна содержать таблица символов? (Код написан на языке обучения, который описан ниже)

Также как мы можем реализовать области в нашей таблице символов?

<PROGRAM> ::= PROGRAM ID <BLOCK> ENDPROGRAM 
<BLOCK> ::= {<DECLARATIONS> <SUBPROGRAMS> <SEQUENCE>} 
<DECLARATIONS> ::= ε | DECLARE <VARLIST> ENDDECLARE 
<VARLIST> ::= ε | ID (, ID)* 
<SUBPROGRAMS> ::= (<PROCORFUNC>) * 
<PROCORFUNC> ::= PROCEDURE ID <PROCORFUNCBODY> ENDPROCEDURE | 
FUNCTION ID <PROCORFUNCBODY> ENDFUNCTION 
<PROCORFUNCBODY> ::= <FORMALPARS> <BLOCK> 
<FORMALPARS> ::= ε | (<FORMALPARLIST>) 
<FORMALPARLIST> ::= <FORMALPARITEM> (, <FORMALPARITEM>)* 
<FORMALPARITEM> ::= IN ID | INOUT ID 
<SEQUENCE> ::= <STATEMENT> (; <STATEMENT>)* 
<STATEMENT> ::= ε | <ASSIGNMENT-STAT> | 
<IF-STAT> | 
<WHILE-STAT> | 
<FOR-STAT> | 
<EXIT-STAT> | 
<CALL-STAT> | 
<RETURN-STAT> 
<ASSIGNMENT-STAT> ::= ID := <EXPRESSION> 
<IF-STAT> ::= IF <CONDITION> THEN <SEQUENCE> <ELSEPART> ENDIF 
<ELSEPART> ::= ε | ELSE <SEQUENCE> 
<WHILE-STAT> ::= DO {<SEQUENCE>} WHILE (<CONDITION>) 
<FOR-STAT> ::= (<ASSIGNMENT-STAT>; <CONDITION>;<ASSIGNMENT-STAT>;) 
{<SEQUENCE>} 
<EXIT-STAT> ::= EXIT 
<CALL-STAT> ::= CALL ID <ACTUALPARS> 
<ACTUALPARS> ::= (<ACTUALPARLIST>) | ε 
<ACTUALPARLIST> ::= <ACTUALPARITEM> (, <ACTUALPARITEM>)* 
<ACTUALPARITEM> ::= IN <EXPRESSION> | INOUT ID 
<RETURN-STAT> ::= RETURN <EXPRESSION> 
<CONDITION> ::= <BOOLTERM> (OR <BOOLTERM>)* 
<BOOLTERM> ::= <BOOLFACTOR> (AND <BOOLFACTOR>)* 
<BOOLFACTOR> ::= NOT [<CONDITION>] | [<CONDITION>] | 
<EXPRESSION> <RELATIONAL-OPER> <EXPRESSION> | 
TRUE | FALSE 
<EXPRESSION> ::= <OPTIONAL-SIGN> <TERM> (<ADD-OPER> <TERM>)* 
<TERM> ::= <FACTOR> (<MUL-OPER> <FACTOR>)* 
<FACTOR> ::= CONSTANT | (<EXPRESSION>) | ID <IDTAIL> 
<IDTAIL> ::= ε | <ACTUALPARS> 
<RELATIONAL-OPER> ::= = | < (ε | = | >) | > (ε | =) 
<ADD-OPER> ::= + | - 
<MUL-OPER> ::= * |/
<OPTIONAL-SIGN> ::= ε | <ADD-OPER> 
PROGRAM MULTIPLY 
    { 
    DECLARE 
    A, B, C 
    ENDDECLARE 
    PROCEDURE Aop(INOUT A) 
    { 
     A=A+1; 
    } 
    ENDPROCEDURE 
    FUNCTION Bop(IN B){ 
     IF [NOT[[TRUE AND FALSE]OR[TRUE]]] THEN B := 100/2; 
     ELSE B := 100; 
     ENDIF; 
     RETURN B; 
     } 
    ENDFUNCTION 
    CALL Aop(INOUT A); 
    CALL Bop(IN B); 
    A := 40; 
    C := A * B; 
    } 
ENDPROGRAM 
+1

Ненавижу, если мой язык программирования всегда кричит мне ... – Bobby

+0

@ Бобби, вам повезло, что вы не использовали 'VT50'. –

+0

Посмотрите на [cactus stackacks] (http://en.wikipedia.org/wiki/Spaghetti_stack) –

ответ

6

таблица отображает символы идентификаторов (как правило, с префиксом именем области видимости) к информации об этом идентификатор, например, его типа символа (локальная переменная/Параметр/функция/класса и т.д.) , тип данных, его порядок относительно других идентификаторов в одной и той же области видимости, строку исходного кода и т. д. Таблицу символов можно создать, пройдя дерево абстрактного синтаксиса, всегда отслеживая, в какой области вы находитесь, и добавляете информацию в таблицу символов всякий раз, когда вы нажимаете объявление переменной. В вашем примере, часть таблицы символов может выглядеть следующим образом (отображение в символьном, тип данных, положения и строки кода источника):

MULTIPLY.A -> {"LOCAL", "INT", 0, 4} 
MULTIPLY.B -> {"LOCAL", "INT", 1, 4} 
MULTIPLY.C -> {"LOCAL", "INT", 2, 4} 
MULTIPLY.Aop -> {"FUNCTION", "INT", 3, 4} 
MULTIPLY.Aop.A -> {"INOUTPARAM", "INT", 0, 6} 

Теперь вы можете разрешить все ссылки на переменные. Например, в выражении A := A + 1, если вы знаете, что ваша текущая область действия равна MULTIPLY.Aop, таблица symnbol позволит вам узнать, что этот A является параметром ввода/вывода типа INT и что это первый параметр (эта информация будет позволяют создавать смещение адреса стека, чтобы вы могли загрузить/сохранить переменную).

Смежные вопросы