2011-12-16 18 views
6

Derleyici yapmak için bir ödevimiz var. Sözcüksel ve sözdizim analizini çoktan yaptık ancak ara kod üretimine bağlı kaldık. Ara kod oluşturma işlemine devam edebilmek için bir sembol tablosu uygulamamız gerektiğini biliyoruz. Bilmiyoruz, nasıl yapılacağını ve içerdiğini biliyoruz.Sembol tablosu nasıl oluşturulur

Aşağıdaki kod verildiğinde, sembol tablosu neyi içermeli? (Kod aşağıda açıklanan bir eğitim dili ile yazılmıştır)

Ayrıca sembol tablolarımızda kapsamları nasıl uygularız?

<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

Programlama dilimin her zaman bana geri bağıyor olmasından nefret ediyorum ... – Bobby

+0

@Bobby, o zaman "VT50" yi kullanmadığınız için şanslısınız. –

+0

[Kaktüs yığınları] 'na bir göz atın (http://en.wikipedia.org/wiki/Spaghetti_stack) –

cevap

6

sembolü tablosu, (vb yerel değişken/parametre/işlev/sınıfı) kendi sembol türü olarak bu tanımlayıcı, ilgili bilgilere (tipik olarak bir kapsam adı ile başlayan) veya tanımlayıcıları haritalar , veri türü, aynı kapsamdaki diğer tanımlayıcılara göre sırası, kaynak kod satırı, vb. Sembol tablosu, her zaman hangi kapsamı izlediğiniz ve bilgi eklediğinizden, özet sözdizimi ağacını geçerek oluşturulabilir. Bir değişken bildirime her vurduğunuzda sembol tablosuna. Örnekte, sembol tablosunun bir parçası bu (sembol türü, veri türü, konum ve kaynak kodu hattına haritalama) gibi görünebilir:

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} 

Şimdi, tüm değişken başvuruları çözebilirsiniz. Örneğin, A := A + 1 ifadesinde, geçerli kapsamınızın MULTIPLY.Aop olduğunu biliyorsanız, symnbol tablosu, bu A'un INT türünde bir girdi/çıktı parametresi olduğunu ve ilk parametre olduğunu (bu bilgi Değişkeni yükleyebilmeniz/depolayabilmeniz için bir yığın adres ofseti oluşturmanıza izin verin).