Commits

Radomir Dopieralski committed 0586755 Draft

2002-11-07

Comments (0)

Files changed (4)

+# Makefile for PasAna
+
+YACC=bison -d
+
+clean:
+	rm -f tp4.tab.c tp4.tab.h
+
+tp4.tab.c: tp4.y
+	$(YACC) tp4.y
+
+tp4.tab.h: tp4.y
+	$(YACC) tp4.y
+
+
+Analizator kodu zrodlowego w Pascalu -- funkcje.
+
+a) Walidacja kodu.
+
+b) Przegladarka tekstowa do zrodel -- z podswietlaniem skladni.
+
+c) Tablice funkcji(procedur), zmiennych, stalych -- razem z miejscami ich
+deklaracji i wywolan -- mozliwosc przeskakiwania w przegladarce.
+
+d) Graf wywolan funkcji (problem z cyklami...).
+
+f) Wykrywanie niewykonywanych fragmentow kodu, zbednych zmiennych, za
+duzych (za malych) tablic, uzycia zmiennych bez inicjowania...
+
+g) Ocena kodu ze wzgledu na kilka metryk (do zbadania).
+
+h) Mozliwosc jednoczesnego przegladania dwoch plikow, wyswietlania ich
+grafow (w celu porownania), etc.
+
+i) Beautifier, mangler.
+
+
+Struktura programu do analizowania kodu Tubo Pascala.
+
+a) Parser.
+
+Parser jest 'sercem', najwaznieszym elementem programu.
+Sklada sie on z tokenizera, tablic symboli oraz wlasciwego
+parsera stworzonego przy pomocy Bisona.
+
+Zadaniem parsera jest stworzenie kompletnego drzewa opisujacego
+strukture programu.
+
+b) Przegladarka kodu.
+
+Pelni ona role podstawowego interface-u. Wyswietla ona kod programu
+z odpowienim kolorowaniem i wcieciami, na podstawie drzewa uzyskanego
+z parsera -- nie jest to wiec wlasciwie przegladarka tekstowa.
+
+Przeladarka ma dzialac w trybie tektowym. Zarowno kolory jak i klawisze
+sterujace maja byc w pelni konfigurowalne przy pomocy odpowiedniego
+pliku tekstowego.
+
+c) Dodatkowe komendy.
+
+Wywolywane beda z przegladarki. Beda to roznorodne opcje, takei jak:
+
+- Wyswietlenie informacji o symbolu
+- Wyswietlenie drzewa wywolan funkcji
+- Policzenie ktorejs z dostepnych metryk
+- Odnalezienie mijsca zdefiniowania, zainicjowania, uzycia danego symbolu
+- Wstawienie komentarza 
+- Zapisanie kodu do pliku (beatyfier)
+- Zapisanie kodu w postaci 'pomieszanej' (mangler)
+
+%start compilation_unit
+
+%token
+
+/* Slowa kluczowe, poprzedzone 'K_' dla odroznienia od innych identyfikatorow (na przyklad FILE).  */
+
+K_AND		K_ABSOLUTE	K_ARRAY			K_BEGIN
+K_CASE		K_CONST		K_DIV			K_DOWNTO
+K_DO		K_ELSE		K_END			K_EXTERNAL
+K_FILE		K_FORWARD	K_FOR			K_FUNCTION
+K_GOTO		K_IF		K_IMPLEMENTATION 	K_INTERFACE
+K_IN		K_LABEL		K_MOD			K_NIL
+K_NOT		K_OF		K_OR			K_PACKED
+K_PROCEDURE	K_PROGRAM	K_RECORD		K_REPEAT
+K_SET		K_SHL		K_SHR			K_STRING
+K_THEN		K_TO		K_TYPE			K_UNIT
+K_UNTIL		K_USES		K_VAR			K_WHILE
+K_WITH		K_XOR
+
+%right K_THEN 
+%right K_ELSE            /* resolve dangling else */
+
+%token
+
+/* Wieloznakowe operatory. */
+
+K_DOTDOT	/* .. */
+K_DEFEQ		/* := */
+K_LEQ		/* <= */
+K_NEQ		/* <> */
+K_GEQ		/* >= */
+
+%token
+
+/* Identyfikatory i stale.  */
+
+/*ID_UNKNOWN*/		/* Identyfikator (zmienna, typ, funkcja, procedura) XXX Rozbic na kilka! */
+ID_FUNC		/* Identyfikator funkcji */
+ID_PROC		/* Identyfikator procedury */
+ID_VAR		/* Identyfikator zmiennej */
+ID_TYPE		/* Identyfikator typu */
+ID_LABEL	/* Identyfikator etykiety */
+ID_UNIT		/* Identyfikator jednostki */
+ID_CONST	/* Identyfikator stalej */
+ID_FIELD	/* Identyfikator pola rekordu */
+ID_NAME		/* Inny identyfikator, przed nadaniem mu znaczenia (przy deklaracji). */
+
+CONST_INT	/* Stala calkowita */
+CONST_REAL	/* Stala zmiennoprzecinkowa */
+CONST_STRING	/* Stala lancuchowa */
+
+%%
+
+compilation_unit
+	: program
+        | unit
+        ;
+
+/* Programs: */
+
+program	: program_heading uses_clause block '.'
+	;
+
+program_heading
+	: /* empty */
+        | K_PROGRAM ID_NAME ';'
+        | K_PROGRAM ID_NAME '(' id_name_list ')' ';'
+	;
+
+uses_clause
+	: /* empty */
+        | K_USES id_unit_list ';'
+        ;
+
+
+/* Listy identyfikatorow roznych rodzajow */
+
+/*
+id_list	: ID_UNKNOWN
+	| id_list ',' ID_UNKNOWN
+        ;
+*/
+
+id_name_list	: ID_NAME
+		| id_name_list ',' ID_NAME
+        	;
+
+id_unit_list	: ID_UNIT
+		| id_unit_list ',' ID_UNIT
+        	;
+
+/* Blok programu */
+
+block	: decl_sect_list compound_stmt
+	;
+
+/* Units: */
+
+unit	: unit_heading interface_part implementation_part
+	  initialization_part '.'
+	;
+
+unit_heading
+	: K_UNIT ID_NAME ';'
+	;
+
+interface_part
+	: K_INTERFACE uses_clause int_decl_sect_list
+        ;
+
+implementation_part
+	: K_IMPLEMENTATION decl_sect_list
+        ;
+
+initialization_part
+	: compound_stmt
+        | K_END
+        ;
+
+/* Declaration sections: */
+
+decl_sect_list
+	: /* empty */
+        | decl_sect_list decl_sect
+        ;
+
+decl_sect
+	: label_decl_sect
+	| const_decl_sect
+	| type_decl_sect
+	| var_decl_sect
+	| proc_decl
+	| func_decl
+	;
+
+label_decl_sect
+	: K_LABEL label_list ';'
+	;
+
+label_list
+	: label_decl
+        | label_list ',' label_decl
+        ;
+
+label	: CONST_INT
+		/* must be decimal integer in the range 0..9999 */
+	| ID_LABEL
+        ;
+
+/* Uzywany przy deklarowaniu etykiet, kiedy jeszcze nie wiemy, ze ID to etykieta */
+label_decl	: CONST_INT
+		| ID_NAME
+        	;
+
+const_decl_sect
+	: K_CONST const_decl
+	| const_decl_sect const_decl
+	;
+
+type_decl_sect
+	: K_TYPE type_decl
+	| type_decl_sect type_decl
+	;
+
+var_decl_sect
+	: K_VAR var_decl
+	| var_decl_sect var_decl
+	;
+
+/* Interface declaration sections: */
+
+/* These appear instead of normal declaration sections in the interface
+   part of a unit. The difference is that there are no label declarations
+   and for procedures and functions only the headings are given. */
+
+int_decl_sect_list
+	: /* empty */
+	| int_decl_sect_list int_decl_sect
+	;
+
+int_decl_sect
+	: const_decl_sect
+	| type_decl_sect
+	| var_decl_sect
+	| proc_heading
+	| func_heading
+	;
+
+/* Constant declarations: */
+
+const_decl
+	: ID_NAME '=' const ';'
+        | ID_NAME ':' type '=' typed_const ';'
+        ;
+
+const	: unsigned_number
+	| sign unsigned_number
+        | ID_CONST
+        | sign ID_CONST
+        | CONST_STRING
+	;
+
+unsigned_number
+	: CONST_INT
+        | CONST_REAL
+        ;
+
+sign	: '+' | '-'
+	;
+
+typed_const
+	: const
+	| array_const
+	| record_const
+        | set_const
+	;
+
+array_const
+	: '(' typed_const_list ')'
+	;
+
+typed_const_list
+	: typed_const
+	| typed_const_list ',' typed_const
+	;
+
+record_const
+	: '(' const_field_list ')'
+	;
+
+const_field_list
+	: const_field
+	| const_field_list ',' const_field
+	;
+
+const_field
+	: ID_FIELD ':' typed_const
+	;
+
+set_const
+	: '[' const_elem_list ']'
+        ;
+
+const_elem_list
+	: /* empty */
+        | const_elem_list1
+        ;
+
+const_elem_list1
+	: const_elem
+	| const_elem_list1 ',' const_elem
+	;
+
+const_elem
+	: const
+	| const K_DOTDOT const
+	;
+
+/* Type declarations: */
+
+type_decl
+	: ID_NAME '=' type ';'
+	;
+
+type	: simple_type
+	| pointer_type
+        | structured_type
+        | string_type
+        ;
+
+simple_type
+	: ID_TYPE
+	| const K_DOTDOT const	/* subrange */
+	| '(' id_name_list ')'	/* enumeration */
+	;
+
+pointer_type
+	: '^' ID_TYPE
+	;
+
+structured_type
+	: unpacked_structured_type
+        | K_PACKED unpacked_structured_type
+        ;
+
+unpacked_structured_type
+	: array_type
+	| record_type
+	| set_type
+	| file_type
+	;
+
+array_type
+	: K_ARRAY '[' simple_type_list ']' K_OF type
+	;
+
+simple_type_list
+	: simple_type
+	| simple_type_list ',' simple_type
+	;
+
+record_type
+	: K_RECORD field_list K_END
+	;
+
+field_list
+	: fixed_part
+	| variant_part
+	| fixed_part ';' variant_part
+	;
+
+fixed_part
+	: record_section
+	| fixed_part ';' record_section
+	;
+
+record_section
+	: /* empty */
+	| id_name_list ':' type
+	;
+
+variant_part
+	: K_CASE tag_field K_OF variant_list
+	;
+
+tag_field
+	: ID_NAME
+	| ID_NAME ':' ID_TYPE
+	;
+
+variant_list
+	: variant
+	| variant_list ';' variant
+	;
+
+variant	: /* empty */
+	| case_tag_list ':' '(' field_list ')'
+	;
+
+case_tag_list
+	: const
+        | case_tag_list ',' const
+        ;
+
+set_type
+	: K_SET K_OF simple_type
+	;
+
+file_type
+	: K_FILE K_OF type
+	| K_FILE
+	;
+
+string_type
+	: K_STRING
+	| K_STRING '[' const ']'
+	;
+
+/* Variable declarations: */
+
+var_decl
+	: id_name_list ':' type absolute_clause ';'
+	;
+
+absolute_clause
+	: /* empty */
+        | K_ABSOLUTE CONST_INT ':' CONST_INT
+        | K_ABSOLUTE ID_VAR
+        ;
+
+/* Procedure and function declarations: */
+
+proc_decl
+	: proc_heading proc_block ';'
+	;
+
+func_decl
+	: func_heading proc_block ';'
+	;
+
+proc_heading
+	: K_PROCEDURE ID_NAME fp_list ';'
+	;
+
+func_heading
+	: K_FUNCTION ID_NAME fp_list ':' fptype ';'
+	;
+
+proc_block         	/* omitted inline and interrupt */
+	: block
+	| K_EXTERNAL
+	| K_FORWARD
+	;
+
+fp_list : /* empty */
+	| '(' fp_sect_list ')'
+	;
+
+fp_sect_list
+	: fp_sect
+	| fp_sect_list ';' fp_sect
+	;
+
+fp_sect	: id_name_list ':' fptype
+	| K_VAR id_name_list ':' fptype
+	| K_VAR id_name_list
+	;
+
+fptype	: ID_TYPE
+	| K_STRING
+	;
+
+/* Statements: */
+
+stmt	: unlabelled_stmt
+	| label ':' unlabelled_stmt
+        ;
+
+unlabelled_stmt
+	: /* empty */
+	| assignment
+	| proc_call
+	| goto_stmt
+	| compound_stmt
+	| if_stmt
+	| case_stmt
+	| repeat_stmt
+	| while_stmt
+	| for_stmt
+	| with_stmt
+	;
+
+assignment
+	: variable K_DEFEQ expr
+	;
+
+proc_call
+	: ID_PROC param_list
+	;
+
+param_list
+	: /* empty */
+	| '(' expr_list ')'
+	;
+
+expr_list
+	: expr
+	| expr_list ',' expr
+	;
+
+goto_stmt
+	: K_GOTO label
+	;
+
+compound_stmt
+	: K_BEGIN stmt_list K_END
+	;
+
+stmt_list
+	: stmt
+	| stmt_list ';' stmt
+	;
+
+if_stmt	: K_IF expr K_THEN stmt
+	| K_IF expr K_THEN stmt K_ELSE stmt
+	;
+
+case_stmt
+	: K_CASE expr K_OF case_list else_case K_END
+	;
+
+case_list
+	: case
+	| case_list ';' case
+	;
+
+case	: /* empty */
+	| case_label_list ':' stmt
+	;
+
+case_label_list
+	: case_label
+        | case_label_list ',' case_label
+        ;
+
+case_label
+	: const
+        | const K_DOTDOT const
+        ;
+
+else_case
+	: /* empty */
+	| K_ELSE stmt
+	| K_ELSE stmt ';'
+	;
+
+repeat_stmt
+	: K_REPEAT stmt_list K_UNTIL expr
+	;
+
+while_stmt
+	: K_WHILE expr K_DO stmt
+	;
+
+for_stmt
+	: K_FOR ID_VAR K_DEFEQ expr K_TO expr K_DO stmt
+	| K_FOR ID_VAR K_DEFEQ expr K_DOWNTO expr K_DO stmt
+	;
+
+with_stmt
+	: K_WITH variable_list K_DO stmt
+	;
+
+variable_list
+	: variable
+        | variable_list ',' variable
+        ;
+
+/* Variables: */
+
+variable
+	: ID_VAR
+	| variable '[' expr_list ']'		/* array component */
+	| variable '.' ID_FIELD			/* record field */
+        | variable '^'				/* pointer value */
+	| ID_TYPE '(' variable ')'		        /* type cast */
+	;
+
+/* Expressions: */
+
+expr	: simple_expr
+	| simple_expr relop simple_expr
+        ;
+
+relop	: '=' | K_NEQ | '<' | '>' | K_LEQ | K_GEQ | K_IN
+        ;
+
+simple_expr
+	: term
+        | sign term
+        | simple_expr addop term
+        ;
+
+addop	: '+' | '-' | K_OR | K_XOR
+	;
+
+term	: factor
+	| term mulop factor
+        ;
+
+mulop	: '*' | '/' | K_DIV | K_MOD | K_SHL | K_SHR | K_AND
+	;
+
+/* Parameterless function calls, and function calls looking like type
+   casts are caught as variables. */
+
+factor	: variable
+	| CONST_INT
+        | CONST_REAL
+        | CONST_STRING
+        | '[' elem_list ']'
+        | K_NIL
+        | '@' variable
+        | '(' expr ')'
+        | ID_FUNC '(' expr_list ')'
+        | K_NOT factor
+        ;
+
+elem_list
+	: /* empty */
+        | elem_list1
+        ;
+
+elem_list1
+	: elem
+	| elem_list1 ',' elem
+	;
+
+elem	: expr
+	| expr K_DOTDOT expr
+	;
+