Как сделать таблицу символов
у нас есть как назначение, чтобы сделать компилятор. Мы уже сделали лексический и синтаксический анализ, но мы застряли в генерации промежуточного кода. Мы поняли, что нам нужно реализовать таблицу символов, чтобы перейти к промежуточной генерации кода, и мы не знаем, как это сделать и что в ней содержится.
учитывая приведенный ниже код, что должна содержать таблица символов? (Код написан на образовательном языке, который описан ниже)
также как можем ли мы реализовать области в нашей таблице символов?
<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 ответов
таблица символов сопоставляет идентификаторы (обычно с префиксом имени области) с информацией об этом идентификаторе, такой как его тип символа (локальная переменная / параметр / функция / класс и т. д.), тип данных, его порядок относительно других идентификаторов в той же области, строка исходного кода и т. д. Таблица символов может быть создана путем обхода дерева абстрактного синтаксиса, всегда отслеживая, в какой области вы находитесь, и добавляя информацию в таблицу символов при каждом нажатии переменной декларация. В вашем примере часть таблицы символов может выглядеть следующим образом (сопоставление с типом символа, типом данных, позицией и строкой исходного кода):
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
, и что это первый параметр (эта информация позволит вам создать смещение адреса стека, чтобы вы могли загрузить / сохранить переменную).