1. Radomir Dopieralski
  2. pasana

Commits

Radomir Dopieralski  committed 1361f21 Draft

2002-12-02

  • Participants
  • Parent commits 0586755
  • Branches default

Comments (0)

Files changed (23)

File Makefile

View file
 # Makefile for PasAna
 
-YACC=bison -d
+YACC=bison -v -d
+CC=gcc
+RM= rm -f
+
+OBJS=tp4.tab.o tokenize.o dict.o parser.o
+PROG=pasana
+
+GLIB_CFLAGS=`glib-config --cflags`
+GLIB_LIBS=`glib-config --libs`
+
+CFLAGS= -ggdb -Wall $(GLIB_CFLAGS) -DDEBUG
+LIBS=$(GLIB_LIBS)
+INCS=-I./
+
+prog: $(OBJS)
+	$(CC) $(LIBS) $(OBJS) -o $(PROG)
+
+test: test_token sample.pas
+	./test_token
 
 clean:
-	rm -f tp4.tab.c tp4.tab.h
+	$(RM) tp4.tab.c tp4.tab.h
+	$(RM) $(OBJS)
+	$(RM) $(PROG)
+	$(RM) test_token token_test.o
 
 tp4.tab.c: tp4.y
 	$(YACC) tp4.y
 
 tp4.tab.h: tp4.y
 	$(YACC) tp4.y
+
+.c.o: $*.c
+	$(CC) $(CFLAGS) $(INCS) -c $*.c -o $@
+
+test_token: token_test.o tokenize.o
+	$(CC) $(LIBS) $^ -o $@
+
+dict.o: dict.c dict.h tp4.tab.h
+dict_test.o: dict_test.c dict.h
+parser.o: parser.c dict.h tokenize.h tp4.tab.h parser.h
+tokenize.o: tokenize.c tokenize.h
+token_test.o: token_test.c tokenize.h
+tp4.tab.o: tp4.tab.c parser.h

File dict.c

View file
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <glib.h>
+#include "dict.h"
+#include "tp4.tab.h"
+
+/* S�owa kluczowe s� globalne. */
+//static GHashTable *keywords_tab;
+
+Dictionary     *
+newDictionary()
+{
+    Dictionary     *dict;
+
+    dict = g_new(Dictionary, 1);
+    dict->table = g_hash_table_new(g_str_hash, g_str_equal);
+    dict->locals = g_hash_table_new(g_str_hash, g_str_equal);
+    return dict;
+}
+
+void
+dictAdd(Dictionary * dict, DictEntry * entry)
+{
+    int i;
+    
+    /* Wszystkie sybole z wielkich liter. */
+    for (i=0; entry->string[i]!='\0'; ++i)
+        entry->string[i] = toupper(entry->string[i]);
+    /* Sprawdzamy, czy taki symbol juz istnieje. */
+    if (g_hash_table_lookup(dict->table, entry->string) != NULL)
+        return;
+    g_hash_table_insert(dict->table, entry->string, entry);
+}
+
+void
+dictAddLocal(Dictionary * dict, DictEntry * entry)
+{
+    int i;
+    
+    /* Wszystkie sybole z wielkich liter. */
+    for (i=0; entry->string[i]!='\0'; ++i)
+        entry->string[i] = toupper(entry->string[i]);
+    /* Sprawdzamy, czy taki symbol juz istnieje. */
+    if (g_hash_table_lookup(dict->locals, entry->string) != NULL)
+        return;
+    g_hash_table_insert(dict->locals, entry->string, entry);
+}
+
+void
+keywordsInit(Dictionary *dict)
+{
+    int             i;
+    const static char *keywords_str[] =
+        {"AND", "ABSOLUTE", "ARRAY", "BEGIN", "CASE", "CONST", "DIV", "DOWNTO", "DO", "ELSE", "END",
+         "EXTERNAL", "FILE", "FORWARD", "FOR", "FUNCTION", "GOTO", "IF", "IMPLEMENTATION",
+         "INTERFACE", "IN", "LABEL", "MOD", "NIL", "NOT", "OF", "OR", "PACKED", "PROCEDURE",
+         "PROGRAM", "RECORD", "REPEAT", "SET", "SHL", "SHR", "STRING", "THEN", "TO", "TYPE", "UNIT",
+         "UNTIL", "USES", "VAR", "WHILE", "WITH", "XOR", "THEN", "ELSE", NULL};
+    const static int keywords_tok[] =
+        {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, K_THEN, K_ELSE, 0};
+
+    dict->keywords = g_hash_table_new(g_str_hash, g_str_equal);
+    for (i = 0; keywords_str[i] != NULL; ++i) {
+        g_hash_table_insert(dict->keywords, (char *)(keywords_str[i]), GINT_TO_POINTER(keywords_tok[i]));
+    }
+}
+
+DictEntry *
+dictLookup(Dictionary * dict, const char *word)
+{
+    DictEntry      *entry;
+    char *upper;
+    int i;
+
+    upper = g_strdup(word);
+    for (i=0; upper[i]!='\0'; ++i)
+        upper[i] = toupper(upper[i]);
+    entry = g_hash_table_lookup(dict->locals, upper);
+    if (entry==NULL)
+        entry = g_hash_table_lookup(dict->table, upper);
+    else
+        printf("Local variable!\n");
+    g_free(upper);
+    return entry;
+}
+
+int
+keywordLookup(Dictionary *dict, const char *word)
+{
+    char *upper;
+    int i;
+    gpointer p;
+
+    upper = g_strdup(word);
+    for (i=0; upper[i]!='\0'; ++i)
+        upper[i] = toupper(upper[i]);
+    p = g_hash_table_lookup(dict->keywords, upper); 
+    g_free(upper);
+    if (p!=NULL)
+        return GPOINTER_TO_INT(p);
+    else
+        return 0;
+}

File dict.h

View file
+/* Slownik i tablice symboli. */
+
+#ifndef DICT_H
+#define DICT_H
+
+struct Dictionary {
+    GHashTable     *locals;
+    GHashTable     *table;
+    GHashTable     *keywords;
+    /* Tu trzeba dodac rozne zakresy i inne takie. */
+};
+typedef struct Dictionary Dictionary;
+
+struct DictEntry {
+    char           *string;                                /* Do jakiego stringa to ma byc hashowane. */
+    int             token;                                 /* Rodzaj tokena do zwrocenia. */
+    /* ... XXX tu musi byc wiecej jeszcze */
+};
+typedef struct DictEntry DictEntry;
+
+/* Szukanie symbolu w slowniku. */
+DictEntry      *dictLookup(Dictionary * dict, const char *word);
+
+/* Wprowadzenie slow kluczowych. */
+void            keywordsInit(Dictionary * dict);
+
+/* Dodanie symbolu do slownika. */
+void            dictAdd(Dictionary * dict, DictEntry * entry);
+void            dictAddLocal(Dictionary * dict, DictEntry * entry);
+
+/* Wyszukiwanie slow kluczowych. */
+int             keywordLookup(Dictionary * dict, const char *word);
+
+/* Utworzenie nowego slownika. */
+Dictionary     *newDictionary();
+
+#endif

File err.txt

View file
+Starting parse
+Entering state 0
+Reading a token: token 296 (unit)
+Next token is 296 (K_UNIT)
+Shifting token 296 (K_UNIT), Entering state 2
+Reading a token: token 316 (Error)
+Next token is 316 (ID_NAME)
+Shifting token 316 (ID_NAME), Entering state 8
+Reading a token: token 59 (;)
+Next token is 59 (';')
+Shifting token 59 (';'), Entering state 15
+Reducing via rule 13 (line 166), K_UNIT ID_NAME ';'  -> unit_heading
+state stack now 0
+Entering state 6
+Reading a token: token 276 (interface)
+Next token is 276 (K_INTERFACE)
+Shifting token 276 (K_INTERFACE), Entering state 11
+Reading a token: token 285 (procedure)
+Next token is 285 (K_PROCEDURE)
+Reducing via rule 7 (line 124),  -> uses_clause
+state stack now 0 6 11
+Entering state 20
+Reducing via rule 39 (line 255),  -> int_decl_sect_list
+state stack now 0 6 11 20
+Entering state 46
+Next token is 285 (K_PROCEDURE)
+Shifting token 285 (K_PROCEDURE), Entering state 31
+Reading a token: token 316 (ShowError)
+Next token is 316 (ID_NAME)
+Shifting token 316 (ID_NAME), Entering state 89
+Reducing via rule 121 (line 544), K_PROCEDURE ID_NAME  -> proc_heading_beginning
+state stack now 0 6 11 20 46
+Entering state 41
+Reading a token: token 40 (()
+Next token is 40 ('(')
+Shifting token 40 ('('), Entering state 97
+Reading a token: token 316 (Msg)
+Next token is 316 (ID_NAME)
+Shifting token 316 (ID_NAME), Entering state 16
+Reducing via rule 9 (line 135), ID_NAME  -> id_name_list
+state stack now 0 6 11 20 46 41 97
+Entering state 155
+Reading a token: token 58 (:)
+Next token is 58 (':')
+Shifting token 58 (':'), Entering state 238
+Reading a token: token 292 (string)
+Next token is 292 (K_STRING)
+Shifting token 292 (K_STRING), Entering state 241
+Reducing via rule 138 (line 609), K_STRING  -> fptype
+state stack now 0 6 11 20 46 41 97 155 238
+Entering state 289
+Reducing via rule 134 (line 590), id_name_list ':' fptype  -> fp_sect
+state stack now 0 6 11 20 46 41 97
+Entering state 157
+Reducing via rule 132 (line 586), fp_sect  -> fp_sect_list
+state stack now 0 6 11 20 46 41 97
+Entering state 156
+Reading a token: token 41 ())
+Next token is 41 (')')
+Shifting token 41 (')'), Entering state 240
+Reducing via rule 131 (line 582), '(' fp_sect_list ')'  -> fp_list
+state stack now 0 6 11 20 46 41
+Entering state 98
+Reading a token: token 59 (;)
+Next token is 59 (';')
+Shifting token 59 (';'), Entering state 158
+Reducing via rule 125 (line 568), proc_heading_beginning fp_list ';'  -> proc_heading
+state stack now 0 6 11 20 46
+Entering state 109
+Reducing via rule 44 (line 263), proc_heading  -> int_decl_sect
+!!! Clearing local namespace!
+state stack now 0 6 11 20 46
+Entering state 108
+Reducing via rule 40 (line 256), int_decl_sect_list int_decl_sect  -> int_decl_sect_list
+state stack now 0 6 11 20
+Entering state 46
+Reading a token: token 275 (implementation)
+Next token is 275 (K_IMPLEMENTATION)
+Reducing via rule 14 (line 172), K_INTERFACE uses_clause int_decl_sect_list  -> interface_part
+state stack now 0 6
+Entering state 12
+Next token is 275 (K_IMPLEMENTATION)
+Shifting token 275 (K_IMPLEMENTATION), Entering state 21
+Reading a token: token 298 (uses)
+Next token is 298 (K_USES)
+Shifting token 298 (K_USES), Entering state 9
+Reading a token: token 316 (Crt)
+Next token is 316 (ID_NAME)
+Shifting token 316 (ID_NAME), Entering state 16
+Reducing via rule 9 (line 135), ID_NAME  -> id_name_list
+state stack now 0 6 12 21 9
+Entering state 17
+Reading a token: token 44 (,)
+Next token is 44 (',')
+Shifting token 44 (','), Entering state 25
+Reading a token: token 316 (Display)
+Next token is 316 (ID_NAME)
+Shifting token 316 (ID_NAME), Entering state 52
+Reducing via rule 10 (line 142), id_name_list ',' ID_NAME  -> id_name_list
+state stack now 0 6 12 21 9
+Entering state 17
+Reading a token: token 59 (;)
+Next token is 59 (';')
+Shifting token 59 (';'), Entering state 24
+Reducing via rule 8 (line 125), K_USES id_name_list ';'  -> uses_clause
+state stack now 0 6 12 21
+Entering state 47
+Reducing via rule 18 (line 195),  -> decl_sect_list
+state stack now 0 6 12 21 47
+Entering state 111
+Reading a token: token 285 (procedure)
+Next token is 285 (K_PROCEDURE)
+Shifting token 285 (K_PROCEDURE), Entering state 31
+Reading a token: token 309 (ShowError)
+Next token is 309 (ID_PROC)
+Shifting token 309 (ID_PROC), Entering state 88
+Reducing via rule 122 (line 549), K_PROCEDURE ID_PROC  -> proc_heading_beginning
+state stack now 0 6 12 21 47 111
+Entering state 41
+Reading a token: token 40 (()
+Next token is 40 ('(')
+Shifting token 40 ('('), Entering state 97
+Reading a token: token 316 (Msg)
+Next token is 316 (ID_NAME)
+Shifting token 316 (ID_NAME), Entering state 16
+Reducing via rule 9 (line 135), ID_NAME  -> id_name_list
+state stack now 0 6 12 21 47 111 41 97
+Entering state 155
+Reading a token: token 58 (:)
+Next token is 58 (':')
+Shifting token 58 (':'), Entering state 238
+Reading a token: token 292 (string)
+Next token is 292 (K_STRING)
+Shifting token 292 (K_STRING), Entering state 241
+Reducing via rule 138 (line 609), K_STRING  -> fptype
+state stack now 0 6 12 21 47 111 41 97 155 238
+Entering state 289
+Reducing via rule 134 (line 590), id_name_list ':' fptype  -> fp_sect
+state stack now 0 6 12 21 47 111 41 97
+Entering state 157
+Reducing via rule 132 (line 586), fp_sect  -> fp_sect_list
+state stack now 0 6 12 21 47 111 41 97
+Entering state 156
+Reading a token: token 41 ())
+Next token is 41 (')')
+Shifting token 41 (')'), Entering state 240
+Reducing via rule 131 (line 582), '(' fp_sect_list ')'  -> fp_list
+state stack now 0 6 12 21 47 111 41
+Entering state 98
+Reading a token: token 59 (;)
+Next token is 59 (';')
+Shifting token 59 (';'), Entering state 158
+Reducing via rule 125 (line 568), proc_heading_beginning fp_list ';'  -> proc_heading
+state stack now 0 6 12 21 47 111
+Entering state 43
+Reading a token: token 260 (begin)
+Next token is 260 (K_BEGIN)
+Reducing via rule 18 (line 195),  -> decl_sect_list
+state stack now 0 6 12 21 47 111 43
+Entering state 19
+Next token is 260 (K_BEGIN)
+Shifting token 260 (K_BEGIN), Entering state 27
+Reading a token: token 309 (WriteXY)
+Next token is 309 (ID_PROC)
+Shifting token 309 (ID_PROC), Entering state 60
+Reading a token: token 40 (()
+Next token is 40 ('(')
+Shifting token 40 ('('), Entering state 138
+Reading a token: token 317 (1)
+Next token is 317 (CONST_INT)
+Shifting token 317 (CONST_INT), Entering state 117
+Reducing via rule 214 (line 760), CONST_INT  -> factor
+state stack now 0 6 12 21 47 111 43 19 27 60 138
+Entering state 130
+Reducing via rule 204 (line 749), factor  -> term
+state stack now 0 6 12 21 47 111 43 19 27 60 138
+Entering state 129
+Reading a token: token 44 (,)
+Next token is 44 (',')
+Reducing via rule 197 (line 741), term  -> simple_expr
+state stack now 0 6 12 21 47 111 43 19 27 60 138
+Entering state 128
+Next token is 44 (',')
+Reducing via rule 188 (line 733), simple_expr  -> expr
+state stack now 0 6 12 21 47 111 43 19 27 60 138
+Entering state 200
+Reducing via rule 156 (line 647), expr  -> expr_list
+state stack now 0 6 12 21 47 111 43 19 27 60 138
+Entering state 199
+Next token is 44 (',')
+Shifting token 44 (','), Entering state 264
+Reading a token: token 317 (25)
+Next token is 317 (CONST_INT)
+Shifting token 317 (CONST_INT), Entering state 117
+Reducing via rule 214 (line 760), CONST_INT  -> factor
+state stack now 0 6 12 21 47 111 43 19 27 60 138 199 264
+Entering state 130
+Reducing via rule 204 (line 749), factor  -> term
+state stack now 0 6 12 21 47 111 43 19 27 60 138 199 264
+Entering state 129
+Reading a token: token 44 (,)
+Next token is 44 (',')
+Reducing via rule 197 (line 741), term  -> simple_expr
+state stack now 0 6 12 21 47 111 43 19 27 60 138 199 264
+Entering state 128
+Next token is 44 (',')
+Reducing via rule 188 (line 733), simple_expr  -> expr
+state stack now 0 6 12 21 47 111 43 19 27 60 138 199 264
+Entering state 304
+Reducing via rule 157 (line 648), expr_list ',' expr  -> expr_list
+state stack now 0 6 12 21 47 111 43 19 27 60 138
+Entering state 199
+Next token is 44 (',')
+Shifting token 44 (','), Entering state 264
+Reading a token: token 319 (Error: )
+Next token is 319 (CONST_STRING)
+Shifting token 319 (CONST_STRING), Entering state 119
+Reducing via rule 216 (line 764), CONST_STRING  -> factor
+state stack now 0 6 12 21 47 111 43 19 27 60 138 199 264
+Entering state 130
+Reducing via rule 204 (line 749), factor  -> term
+state stack now 0 6 12 21 47 111 43 19 27 60 138 199 264
+Entering state 129
+Reading a token: token 43 (+)
+Next token is 43 ('+')
+Reducing via rule 197 (line 741), term  -> simple_expr
+state stack now 0 6 12 21 47 111 43 19 27 60 138 199 264
+Entering state 128
+Next token is 43 ('+')
+Shifting token 43 ('+'), Entering state 179
+Reducing via rule 200 (line 746), '+'  -> addop
+state stack now 0 6 12 21 47 111 43 19 27 60 138 199 264 128
+Entering state 184
+Reading a token: token 310 (Msg)
+Next token is 310 (ID_VAR)
+Shifting token 310 (ID_VAR), Entering state 61
+Reducing via rule 183 (line 722), ID_VAR  -> variable
+state stack now 0 6 12 21 47 111 43 19 27 60 138 199 264 128 184
+Entering state 126
+Reading a token: token 41 ())
+Next token is 41 (')')
+Reducing via rule 213 (line 759), variable  -> factor
+state stack now 0 6 12 21 47 111 43 19 27 60 138 199 264 128 184
+Entering state 130
+Reducing via rule 204 (line 749), factor  -> term
+state stack now 0 6 12 21 47 111 43 19 27 60 138 199 264 128 184
+Entering state 255
+Next token is 41 (')')
+Reducing via rule 199 (line 743), simple_expr addop term  -> simple_expr
+state stack now 0 6 12 21 47 111 43 19 27 60 138 199 264
+Entering state 128
+Next token is 41 (')')
+Reducing via rule 188 (line 733), simple_expr  -> expr
+state stack now 0 6 12 21 47 111 43 19 27 60 138 199 264
+Entering state 304
+Reducing via rule 157 (line 648), expr_list ',' expr  -> expr_list
+state stack now 0 6 12 21 47 111 43 19 27 60 138
+Entering state 199
+Next token is 41 (')')
+Shifting token 41 (')'), Entering state 263
+Reducing via rule 155 (line 643), '(' expr_list ')'  -> param_list
+state stack now 0 6 12 21 47 111 43 19 27 60
+Entering state 139
+Reducing via rule 153 (line 637), ID_PROC param_list  -> proc_call
+state stack now 0 6 12 21 47 111 43 19 27
+Entering state 69
+Reducing via rule 143 (line 621), proc_call  -> unlabelled_stmt
+state stack now 0 6 12 21 47 111 43 19 27
+Entering state 67
+Reducing via rule 139 (line 614), unlabelled_stmt  -> stmt
+state stack now 0 6 12 21 47 111 43 19 27
+Entering state 66
+Reducing via rule 160 (line 660), stmt  -> stmt_list
+state stack now 0 6 12 21 47 111 43 19 27
+Entering state 72
+Reading a token: token 59 (;)
+Next token is 59 (';')
+Shifting token 59 (';'), Entering state 143
+Reading a token: token 267 (end)
+Next token is 267 (K_END)
+Reducing via rule 141 (line 619),  -> unlabelled_stmt
+state stack now 0 6 12 21 47 111 43 19 27 72 143
+Entering state 67
+Reducing via rule 139 (line 614), unlabelled_stmt  -> stmt
+state stack now 0 6 12 21 47 111 43 19 27 72 143
+Entering state 203
+Reducing via rule 161 (line 661), stmt_list ';' stmt  -> stmt_list
+state stack now 0 6 12 21 47 111 43 19 27
+Entering state 72
+Next token is 267 (K_END)
+Shifting token 267 (K_END), Entering state 142
+Reducing via rule 159 (line 656), K_BEGIN stmt_list K_END  -> compound_stmt
+state stack now 0 6 12 21 47 111 43 19
+Entering state 45
+Reducing via rule 11 (line 153), decl_sect_list compound_stmt  -> block
+state stack now 0 6 12 21 47 111 43
+Entering state 102
+Reducing via rule 127 (line 576), block  -> proc_block
+state stack now 0 6 12 21 47 111 43
+Entering state 103
+Reading a token: token 59 (;)
+Next token is 59 (';')
+Shifting token 59 (';'), Entering state 160
+Reducing via rule 119 (line 524), proc_heading proc_block ';'  -> proc_decl
+!!! Clearing local namespace!
+state stack now 0 6 12 21 47 111
+Entering state 39
+Reducing via rule 24 (line 204), proc_decl  -> decl_sect
+state stack now 0 6 12 21 47 111
+Entering state 34
+Reducing via rule 19 (line 196), decl_sect_list decl_sect  -> decl_sect_list
+state stack now 0 6 12 21 47
+Entering state 111
+Reading a token: token 267 (end)
+Next token is 267 (K_END)
+Reducing via rule 15 (line 178), K_IMPLEMENTATION uses_clause decl_sect_list  -> implementation_part
+state stack now 0 6 12
+Entering state 22
+Next token is 267 (K_END)
+Shifting token 267 (K_END), Entering state 48
+Reducing via rule 17 (line 187), K_END  -> initialization_part
+state stack now 0 6 12 22
+Entering state 49
+Reading a token: token 46 (.)
+Next token is 46 ('.')
+Shifting token 46 ('.'), Entering state 112
+Reducing via rule 12 (line 160), unit_heading interface_part implementation_part initialization_part '.'  -> unit
+state stack now 0
+Entering state 5
+Reducing via rule 2 (line 103), unit  -> compilation_unit
+state stack now 0
+Entering state 391
+Reading a token: token 0 ()
+Now at end of input.
+Shifting token 0 ($), Entering state 392
+Now at end of input.

File error.pas

View file
+
+{ Copyright (c) 1985, 1989 by Borland International, Inc. }
+
+unit Error;
+{ Sample unit for CIRCULAR.PAS }
+
+interface
+
+procedure ShowError(Msg : string);
+
+implementation
+
+uses
+  Crt, Display;
+
+procedure ShowError(Msg : string);
+begin
+  WriteXY(1, 25, 'Error: ' + Msg);
+end;
+
+end.

File lexer.c

View file
+/* Funkcje wymagane przez Bisona i uzywane wewnatrz parsera. */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <glib.h>
+
+#include "symbol.h"
+#include "tokenize.h"
+#include "tp4.tab.h"
+#include "parser.h"
+#include "lexer.h"
+
+int
+get_token(Parser *parser, YYSTYPE (*lvalp))
+{
+    Symbol         *sym;
+    DictEntry      *entry;
+    int             temp;
+    
+    for (;;)
+        switch (getNextToken(parser->tok)) {
+            case TOKEN_CHAR:
+                return parser->tok->buf->str[0];
+            case TOKEN_EOF:
+                return 0;
+            case TOKEN_INT:
+            case TOKEN_HEX:
+                (*lvalp).const_int = atoi(parser->tok->buf->str);
+                return CONST_INT;
+            case TOKEN_REAL:
+            case TOKEN_ENG:
+                (*lvalp).const_real = atof(parser->tok->buf->str);
+                return CONST_REAL;
+            case TOKEN_STRING:
+                (*lvalp).string = parser->tok->buf->str;
+                return CONST_STRING;
+            case TOKEN_DEFEQ:
+                return OP_DEFEQ;
+            case TOKEN_DOTDOT:
+                return OP_DOTDOT;
+            case TOKEN_LEQ:
+                return OP_LEQ;
+            case TOKEN_GEQ:
+                return OP_GEQ;
+            case TOKEN_NEQ:
+                return OP_NEQ;
+            case TOKEN_NAME:
+                temp = findKeyword(parser, parser->tok->buf->str);
+                if (temp != 0)
+                    return temp;
+                sym = findSymbol(parser, parser->tok->buf->str);
+                if (sym != NULL) {
+                    (*lvalp).symbol = sym;
+                    return sym->token;
+                }
+                (*lvalp).string = parser->tok->buf->str;
+                return ID_NAME;
+            case TOKEN_COMMENT:
+                /* Nothing */
+                break;
+            case TOKEN_ERROR:
+                break;
+            default:
+                return 0;
+        }
+}
+
+
+int
+yylex (YYSTYPE *lvalp, Parser *parser)
+{
+    int token;
+
+    token = get_token(parser, lvalp);
+#ifdef DEBUG
+    fprintf(stderr, "token %d (%s)\n", token, parser->tok->buf->str); 
+#endif
+    return token;
+}
+
+void
+yyerror(char *msg)
+{
+    fprintf(stderr, "%s\n", msg);
+}

File lexer.h

View file
+#ifndef LEXER_H
+#define LEXER_H
+
+/* Skaner leksykalny. */
+int yylex (YYSTYPE *lvalp, Parser *parser);
+
+/* Obsluga bledow. */
+void yyerror(char *msg);
+#endif

File main.c

View file
+/* Funkcje wymagane przez Bisona i uzywane wewnatrz parsera. */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <glib.h>
+
+#include "symbol.h"
+#include "tokenize.h"
+#include "tp4.tab.h"
+#include "parser.h"
+
+/* To jest w tp4.tab.c */
+int             yyparse();
+extern int      yydebug;
+
+
+int
+main(int argc, char *argv[])
+{
+    Parser *parser;
+
+    if (argc<2)
+        parser = newParser("sample.pas");
+    else
+        parser = newParser(argv[1]);
+
+    /* Tymczasowo, potem to bedzie w unicie 'system'. */
+    registerType(parser, "integer");
+    registerType(parser, "real");
+    registerType(parser, "char");
+
+    registerProc(parser, "write");
+    registerProc(parser, "writexy");
+    registerProc(parser, "writeln");
+
+    registerFunc(parser, "read");
+    registerFunc(parser, "readln");
+
+#ifdef DEBUG
+    yydebug = TRUE;
+#endif
+    return yyparse(parser);
+}

File parse_misc.c

View file
+/* Rozne procedury uzywane przez parsera. */
+
+#include <glib.h>
+#include "parser.h"
+#include "parse_misc.h"
+
+/* Wyszukuje slowo kluczowe. */
+int
+findKeyword(Parser *parser, const char *word)
+{
+    GString *upper;
+    gpointer p;
+
+    upper = g_string_new(word);
+    upper = g_string_up(upper);
+    p = g_hash_table_lookup(parser->keywords, (gpointer)(upper->str)); 
+    g_string_free(upper);
+    if (p!=NULL)
+        return GPOINTER_TO_INT(p);
+    else
+        return 0;
+}
+
+Symbol *
+findSymbol(Parser *parser, const char *name)
+{
+    Symbol *sym;
+    Namespace *nam;
+
+    nam = parser->actual;
+    while (nam!=NULL) {
+        sym = getSymbol(parser->nam, name);
+        if (sym!=NULL)
+            return sym;
+        if (nam->owner!=NULL)
+            nam = nam->owner->contained;
+        else
+            nam = NULL;
+    }
+    return nam;
+}

File parse_misc.h

View file
+#ifndef PARSE_MISC_H
+#define PARSE_MISC_H
+
+/* Wyszukuje slowo kluczowe. */
+int
+findKeyword(Parser *parser, const char *word)
+
+#endif

File parser.c

View file
+/* Funkcje wymagane przez Bisona i uzywane wewnatrz parsera. */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <glib.h>
+
+#include "symbols.h"
+#include "tokenize.h"
+#include "tp4.tab.h"
+#include "parser.h"
+
+/* Wpisuje do tablicy slowa kluczowe. */
+void
+initKeywords(Parser * parser)
+{
+    int             i;
+    const static char *keywords_str[] =
+        { "AND", "ABSOLUTE", "ARRAY", "BEGIN", "CASE", "CONST", "DIV", "DOWNTO", "DO", "ELSE",
+"END", "EXTERNAL", "FILE", "FORWARD", "FOR", "FUNCTION", "GOTO", "IF", "IMPLEMENTATION", "INTERFACE", "IN", "LABEL",
+"MOD", "NIL", "NOT", "OF", "OR", "PACKED", "PROCEDURE", "PROGRAM", "RECORD", "REPEAT", "SET", "SHL", "SHR", "STRING",
+"THEN", "TO", "TYPE", "UNIT", "UNTIL", "USES", "VAR", "WHILE", "WITH", "XOR", "THEN", "ELSE", NULL };
+    const static int keywords_tok[] =
+        { 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, K_THEN, K_ELSE, 0 };
+
+    for (i = 0; keywords_str[i] != NULL; ++i) {
+        g_hash_table_insert(parser->keywords, (char *)(keywords_str[i]),
+                            GINT_TO_POINTER(keywords_tok[i]));
+    }
+}
+
+/* Tworzy nowy parser. */
+Parser         *
+newParser(const char *filename)
+{
+    Parser         *parser;
+
+    parser = g_new(Parser, 1);
+    parser->filename = g_string_new(filename);
+    parser->global = newNamespace(NULL);
+    parser->actual = parser->global;
+
+    parser->tok = newTokenizer(filename);
+    parser->keywords = g_hash_table_new(g_str_hash, g_str_equal);
+    initKeywords(parser);
+    return parser;
+}
+
+/* Niszczy parser. */
+void
+destroyParser(Parser * parser)
+{
+    g_string_free(parser->filename, TRUE);
+    destroyNamespace(parser->global);
+
+    destroyTokenizer(parser->tok);
+    g_hash_table_destroy(parser->keywords);
+    g_free(parser);
+    parser = NULL;
+}

File parser.h

View file
+/* Struktura parsera. */
+
+#ifndef PARSER_H
+#define PARSER_H
+
+struct Parser {
+    GString        *filename;                              /* Nazwa pliku zrodlowego. */
+    GHashTable     *keywords;                              /* Tablica slow kluczowych. */
+    Namespace      *global;                                /* Globalna przestrzen nazw. */
+    Namespace      *actual;                                /* Aktualna przestrzen nazw. */
+    Tokenizer      *tok;                                   /* Tokenizer. */
+};
+typedef struct Parser Parser;
+
+/* Tworzy nowy parser. */
+Parser         *newParser(const char *filename);
+
+/* Niszczy parser. */
+void            destroyParser(Parser * parser);
+#endif

File pascal.l

View file
+/* Tokenizer dla jezyka Turbo Pascal */
+
+%{ 
+	#include "pascal.tab.h"
+%}
+
+%option noyywrap case-insensitive never-interactive 8bit verbose debug batch nointeractive
+
+SPC	[ \t\v\r]
+DIG	[0-9]
+NUM	{DIG}+
+HEX	[0-9a-f]
+ID1ST	[_a-z]
+IDNTH	[_a-z0-9]
+SIGN	[+-]
+CTRL	"^"[@a-z\[\]\\]
+CHASH	("#"{DIG}{1,3})|("#$"{HEX}{1,2})
+QTEXT	[^'\n]|"''"
+COMMENT	("{"[^}]*"}")|("(*"([^*]|"*"[^)*]|"**"[^)])*"*)")
+
+%%
+
+{ID1ST}{IDNTH}*		{
+				/* Identyfikator lub slowo kluczowe */
+				return ID_NAME;
+			}
+{NUM}			{
+				/* Stala calkowita */
+				printf("INT_CONST <%s>\n", yytext);
+			}
+({NUM}"."{NUM})|({NUM}("."{NUM})?"e"{SIGN}?{NUM}) {
+				/* Stala zmiennoprzecinkowa */
+				printf("REAL_CONST <%s>\n", yytext);
+			}
+"$"{HEX}+		{
+				/* Stala szesnastkowa */
+				printf("HEX_CONST <%s>\n", yytext);
+			}
+("'"{QTEXT}"'")|{CTRL}|{CHASH} {
+				/* Stala znakowa (pojedynczy znak) */
+				printf("CHAR_CONST <%s>\n", yytext);
+			}
+(("'"{QTEXT}*"'")|{CTRL}|{CHASH})+ {
+				/* Stala lancuchowa */
+				printf("STR_CONST <%s>\n", yytext);
+			}
+^{SPC}*{COMMENT}(({SPC}|\n)*{COMMENT})* {
+				/* Komentarz blokowy XXX trzeba policzyc konce linii! */
+				printf("BLOCK_COMMENT <%s>\n", yytext);
+			}
+{COMMENT}({SPC}*{COMMENT})* {
+				/* Komentarz zwykly  typu {...} lub (*...*) */
+				printf("COMMENT <%s>\n", yytext);
+			}
+":="			{
+				/* Symbole dwuznakowe */
+				printf("TWOCHAR <%s>\n", yytext);
+			}
+"<>"			{
+				/* Symbole dwuznakowe */
+				printf("TWOCHAR <%s>\n", yytext);
+			}
+"<="			{
+				/* Symbole dwuznakowe */
+				printf("TWOCHAR <%s>\n", yytext);
+			}
+
+">="			{
+				/* Symbole dwuznakowe */
+				printf("TWOCHAR <%s>\n", yytext);
+			}
+
+".."			{
+				/* Symbole dwuznakowe */
+				printf("TWOCHAR <%s>\n", yytext);
+			}
+
+"(."|"["		{
+				printf("CHARACTER <[>\n");
+			}
+
+".)"|"]"		{
+				printf("CHARACTER <]>\n");
+			}
+[-+*/=^<>().,:;'@]	{
+				/* Pojedyncze dozwolone symbole */
+				printf("CHARACTER <%s>\n", yytext);
+			}
+{SPC}+			{ /* Pomijanie odstepow */ }
+\n			{ /* Liczenie linii */ }
+.			{
+				/* Bledy: znaki takie, jak &%~`{}\"?! */
+				printf("ILLEGAL <%s>\n", yytext);
+			}
+%%
+/*
+<<EOF>>			{
+				printf("EOF <%s>\n", yytext);
+				return;
+			}
+*/

File sample.pas

View file
+PROGRAM Sample;
+
+{ Comment 1 *) }
+(* Comment 2 } *)
+
+PROCEDURE Smpl_1;
+VAR	v: integer;
+BEgIN
+	v := (1+2)*2;
+END;
+
+BEGIN
+	IF (1 >= $02) THEN BEGIN
+	END;
+	WriteLn('Hello world!'^I''''#64 + 'Hi!');
+END.

File symbols.c

View file
+/* Obsluga przestrzeni nazw i symboli. */
+
+#include <glib.h>
+#include "symbols.h"
+
+/* Tworzy nowa przestrzen nazw o podanym wlascicielu. */
+Namespace      *
+newNamespace(Symbol * owner)
+{
+    Namespace      *nam;
+
+    nam = g_new(Namespace, 1);
+    nam->owner = owner;
+    nam->table = g_hash_table_new(g_str_hash, g_str_equal);
+    return nam;
+}
+
+/* niszczy poszczegolne elementy tablicy w przestrzeni nazw. */
+void
+foreachDestroyNamespace(gpointer name, gpointer symbol, gpointer user_data)
+{
+    destroySymbol(symbol);
+    g_free(name);
+}
+
+/* Niszczy przestrzen nazw. */
+void
+destroyNamespace(Namespace * nam)
+{
+    if (nam == NULL)
+        return;
+    g_hash_table_foreach(nam->table, foreachDestroyNamespace, NULL);
+    g_hash_table_destroy(nam->table);
+    g_free(nam);
+    nam = NULL;
+}
+
+/* Tworzy nowy symbol. */
+Symbol         *
+newSymbol(const char *name, int token, Type * type)
+{
+    Symbol         *sym;
+
+    sym = g_new(Symbol, 1);
+    sym->name = g_string_new(name);
+    sym->contained = NULL;
+    sym->namespace = NULL;
+    sym->token = token;
+    sym->type = type;
+    return sym;
+}
+
+/* Niszczy symbol (nie usuwa go z przestrzeni nazw!) */
+void
+destroySymbol(Symbol * sym)
+{
+    if (sym == NULL)
+        return;
+    g_string_free(sym->name, TRUE);
+    destroyNamespace(sym->namespace);
+    destroyType(sym->type);
+    g_free(sym);
+    sym = NULL;
+}
+
+/* Tworzy nowy opis typu. */
+Type           *
+newType(Symbol * base)
+{
+    Type           *type;
+
+    type = g_new(Type, 1);
+    type->base = base;
+    type->mods = g_string_new("");
+    return type;
+}
+
+/* Niszczy opis typu. */
+void
+destroyType(Type * type)
+{
+    if (type == NULL)
+        return;
+    g_string_free(type->mods, TRUE);
+    g_free(type);
+}
+
+/* Dodaje symbol do przestrzeni nazw. */
+void
+addSymbol(Namespace * nam, Symbol * sym)
+{
+    GString        *key;
+
+    key = g_string_new(sym->name->str);
+    key = g_string_up(key);
+    g_hash_table_insert(nam->table, (gpointer) (key->str), (gpointer) sym);
+    g_string_free(key, FALSE);
+    sym->contained = nam;
+}
+
+/* Wyszukuje symbol w przestrzeni nazw. */
+Symbol*
+getSymbol(Namespace * nam, char *name)
+{
+    Symbol         *sym;
+    GString        *key;
+
+    key = g_string_new(name);
+    key = g_string_up(key);
+    sym = g_hash_table_lookup(nam->table, (gpointer) (key->str));
+    g_string_free(key, TRUE);
+    return sym;
+}

File symbols.h

View file
+#ifndef SYMBOLS_H
+#define SYMBOLS_H
+
+/* Opis typu symbolu. */
+struct Type {
+    Symbol         *base;                                  /* Typ bazowy. */
+    GString        *mods;                                  /* Informacje o wskaznikach, tablicach, plikach itp. */
+};
+typedef struct Type Type;
+
+/* Opis symbolu. */
+struct Symbol {
+    GString        *name;                                  /* Oryginalna nazwa symbolu (z zachowana wielkoscia liter). */
+    Namespace      *contained;                             /* Do jakiej przestrzeni nalezy ten symbol. */
+    Namespace      *namespace;                             /* Wlasna przestrzen nazw. */
+    int             token;                                 /* Jakiego jest typu (jaki zwraca token). */
+    Type           *type;                                  /* Jakiego jest typu. */
+};
+typedef struct Symbol Symbol;
+
+/* Przestrzen nazw. */
+struct Namespace {
+    Symbol         *owner;                                 /* Do jakiego symbolu nalezy ta przestrzen. */
+    GHashTable     *table;                                 /* Tablica symboli. */
+};
+typedef struct Namespace Namespace;
+
+/* Tworzy nowa przestrzen nazw o podanym wlascicielu. */
+Namespace      *newNamespace(Symbol * owner);
+
+/* Niszczy przestrzen nazw. */
+void            destroyNamespace(Namespace * nam);
+
+/* Tworzy nowy symbol. */
+Symbol         *newSymbol(const char *name, int token, Type * type);
+
+/* Niszczy symbol (nie usuwa go z przestrzeni nazw!) */
+void            destroySymbol(Symbol * sym);
+
+/* Tworzy nowy opis typu. */
+Type           *newType(Symbol * base);
+
+/* Niszczy opis typu. */
+void            destroyType(Type * type);
+
+/* Dodaje symbol do przestrzeni nazw. */
+void            addSymbol(Namespace * nam, Symbol * sym);
+
+/* Wyszukuje symbol w przestrzeni nazw. */
+Symbol         *getSymbol(Namespace * nam, char *name);
+#endif

File token_test.c

View file
+#include <stdlib.h>
+#include <stdio.h>
+#include <glib.h>
+#include "tokenize.h"
+
+/* Prosty programik testujacy tokenizera. */
+int
+main(int argc, char *argv[])
+{
+    Tokenizer      *tok;
+
+    tok = newTokenizer("sample.pas");
+    while (getNextToken(tok) != TOKEN_EOF) {
+        printf("type: %d, string: (%s)\n", tok->type, tok->buf->str);
+    }
+    destroyTokenizer(tok);
+    return 0;
+}

File tokenize.c

View file
+#include <stdlib.h>
+#include <stdio.h>
+#include <glib.h>
+#include <ctype.h>
+
+#include "tokenize.h"
+
+/* Tworzy nowego tokenizera. */
+Tokenizer      *
+newTokenizer(const char *filename)
+{
+    FILE           *f;
+    Tokenizer      *tok;
+
+    f = fopen(filename, "r");
+    if (f == NULL)
+        return NULL;
+    tok = g_new(Tokenizer, 1);
+    tok->source = f;
+    tok->bufpos = 0;
+    tok->filename = g_strdup(filename);
+    tok->line = 1;
+    tok->position = 0;
+    tok->c = '\0';
+    tok->putback = '\0';
+    tok->buf = g_string_sized_new(32);
+    return tok;
+}
+
+/* Niszczy tokenizera. */
+void
+destroyTokenizer(Tokenizer * tok)
+{
+    g_string_free(tok->buf, TRUE);
+    fclose(tok->source);
+    g_free(tok->filename);
+    g_free(tok);
+    return;
+}
+
+/* Czyta pojedynczy znak. Ustawia position i line. */
+unsigned int
+getTokenizerChar(Tokenizer * tok)
+{
+    if (tok->putback == '\0') {
+        tok->c = fgetc(tok->source);
+        if (tok->c == '\n')
+            ++(tok->line);
+        ++(tok->position);
+    } else {
+        tok->c = tok->putback;
+        tok->putback = '\0';
+    }
+    return tok->c;
+}
+
+/* Dodaje znaczek do bufora. */
+void
+putTokenizerChar(Tokenizer * tok, char c)
+{
+#if 0
+    tok->buffer[tok->bufpos] = c;
+    if (tok->bufpos < TOKEN_SIZE - 1)
+        ++(tok->bufpos);
+#endif
+    tok->buf = g_string_append_c(tok->buf, c);
+    return;
+}
+
+/* Parsuje wyrazenia typu 'kflhgla''ajgkl' do stringa */
+void
+TokenizeQuotes(Tokenizer * tok)
+{
+    for (;;) {
+        if (getTokenizerChar(tok) == '\'') {
+            if (getTokenizerChar(tok) != '\'')
+                return;
+        }
+        putTokenizerChar(tok, tok->c);
+    }
+}
+
+/* Parsuje wyrazenia typu #123 do stringa */
+void
+TokenizeHash(Tokenizer * tok)
+{
+    int             code;
+    GString         *buf;
+
+    buf = g_string_sized_new(16);
+    if (tok->c != '#')
+        return;
+    while (isdigit(getTokenizerChar(tok))) {
+        buf = g_string_append_c(buf, tok->c);
+    }
+    code = atoi(buf->str);
+    putTokenizerChar(tok, code);
+    g_string_free(buf, TRUE);
+    return;
+}
+
+/* Parsuje wyrazenia typu ^C do stringa */
+void
+TokenizeCtrl(Tokenizer * tok)
+{
+    int             code;
+
+    tok->c = toupper(tok->c);
+    code = (tok->c - 'A') + 1;
+    putTokenizerChar(tok, code);
+    getTokenizerChar(tok);
+    return;
+}
+
+/* Wczytuje do tokenizera nastepny token. */
+enum TOKEN_TYPE
+getNextToken(Tokenizer * tok)
+{
+
+    /* Nie czytamy z pustego tokenizera. */
+    if (tok == NULL)
+        return TOKEN_EOF;
+    /* Oprozniamy bufor. */
+    tok->buf = g_string_truncate(tok->buf, 0);
+    tok->bufpos = 0;
+    /* Wczytujemy pierwszy znak z pliku. */
+    if (tok->c == '\0')
+        getTokenizerChar(tok);
+
+    /* Pomijamy odstepy. */
+    while (isspace(tok->c))
+        getTokenizerChar(tok);
+
+    /* Maszyna stanow (automaton) */
+    if (isdigit(tok->c)) {
+        /* Jesli zaczyna sie od cyfry... */
+        putTokenizerChar(tok, tok->c);
+        while (isdigit(getTokenizerChar(tok))) {
+            putTokenizerChar(tok, tok->c);
+        }
+        /* Koniec cyfr. */
+        if (tok->c == '.') {
+            /* Jeszcze czesc ulamkowa. */
+            /* Uwaga! Ta kropka moze byc od '..'! */
+            getTokenizerChar(tok);
+            if (isdigit(tok->c)) {
+                putTokenizerChar(tok, '.');
+                putTokenizerChar(tok, tok->c);
+                while (isdigit(getTokenizerChar(tok))) {
+                    putTokenizerChar(tok, tok->c);
+                }
+                putTokenizerChar(tok, '\0');
+                tok->type = TOKEN_REAL;
+                return tok->type;
+            } else {
+                /* To nie byla jednak kropka od ulamka. */
+                tok->putback = tok->c;
+                tok->c = '.';
+                putTokenizerChar(tok, '\0');
+                tok->type = TOKEN_INT;
+                return tok->type;
+            }
+        } else if (toupper(tok->c) == 'E') {
+            /* Jeszcze znak i potega po 'e'. */
+            putTokenizerChar(tok, 'e');
+            getTokenizerChar(tok);
+            if ((tok->c == '+') || (tok->c == '-') || (isdigit(tok->c))) {
+                putTokenizerChar(tok, tok->c);
+            } else {
+                putTokenizerChar(tok, '\0');
+                tok->type = TOKEN_ERROR;
+                return tok->type;
+            }
+            while (isdigit(getTokenizerChar(tok))) {
+                putTokenizerChar(tok, tok->c);
+            }
+            putTokenizerChar(tok, '\0');
+            tok->type = TOKEN_ENG;
+            return tok->type;
+        }
+        /* Ewentualnie moze to byc tylko liczba calkowita. */
+        putTokenizerChar(tok, '\0');
+        tok->type = TOKEN_INT;
+        return tok->type;
+    } else if (isalpha(tok->c) || (tok->c == '_')) {
+        /* Mamy identyfikator. */
+        putTokenizerChar(tok, tok->c);
+        while (isalnum(getTokenizerChar(tok)) || (tok->c == '_')) {
+            putTokenizerChar(tok, tok->c);
+        }
+        putTokenizerChar(tok, '\0');
+        tok->type = TOKEN_NAME;
+        return tok->type;
+    } else {
+        switch (tok->c) {
+            case EOF:
+                tok->type = TOKEN_EOF;
+                return tok->type;
+            case ':':
+                getTokenizerChar(tok);
+                if (tok->c == '=') {
+                    tok->type = TOKEN_DEFEQ;
+                    putTokenizerChar(tok, ':');
+                    putTokenizerChar(tok, '=');
+                    putTokenizerChar(tok, '\0');
+                    getTokenizerChar(tok);
+                    return tok->type;
+                } else {
+                    tok->type = TOKEN_CHAR;
+                    putTokenizerChar(tok, ':');
+                    putTokenizerChar(tok, '\0');
+                    getTokenizerChar(tok);
+                    return tok->type;
+                }
+            case '.':
+                getTokenizerChar(tok);
+                if (tok->c == '.') {
+                    tok->type = TOKEN_DOTDOT;
+                    putTokenizerChar(tok, '.');
+                    putTokenizerChar(tok, '.');
+                    putTokenizerChar(tok, '\0');
+                    getTokenizerChar(tok);
+                } else {
+                    tok->type = TOKEN_CHAR;
+                    putTokenizerChar(tok, '.');
+                    putTokenizerChar(tok, '\0');
+                }
+                return tok->type;
+            case '>':
+                getTokenizerChar(tok);
+                if (tok->c == '=') {
+                    tok->type = TOKEN_GEQ;
+                    putTokenizerChar(tok, '>');
+                    putTokenizerChar(tok, '=');
+                    putTokenizerChar(tok, '\0');
+                    getTokenizerChar(tok);
+                    return tok->type;
+                } else {
+                    tok->type = TOKEN_CHAR;
+                    putTokenizerChar(tok, '>');
+                    putTokenizerChar(tok, '\0');
+                    return tok->type;
+                }
+            case '<':
+                getTokenizerChar(tok);
+                if (tok->c == '=') {
+                    tok->type = TOKEN_LEQ;
+                    putTokenizerChar(tok, '<');
+                    putTokenizerChar(tok, '=');
+                    putTokenizerChar(tok, '\0');
+                    getTokenizerChar(tok);
+                    return tok->type;
+                } else if (tok->c == '>') {
+                    tok->type = TOKEN_NEQ;
+                    putTokenizerChar(tok, '<');
+                    putTokenizerChar(tok, '>');
+                    putTokenizerChar(tok, '\0');
+                    getTokenizerChar(tok);
+                    return tok->type;
+                } else {
+                    tok->type = TOKEN_CHAR;
+                    putTokenizerChar(tok, '<');
+                    putTokenizerChar(tok, '\0');
+                    return tok->type;
+                }
+            case '^':
+                if (!isalpha(getTokenizerChar(tok))) {
+                    tok->type = TOKEN_CHAR;
+                    putTokenizerChar(tok, tok->c);
+                    putTokenizerChar(tok, '\0');
+                    getTokenizerChar(tok);
+                    return tok->type;
+                }
+                TokenizeCtrl(tok);
+                /*@falltrough@*/
+            case '\'':
+            case '#':
+                for (;;) {
+                    if (tok->c == '\'') {
+                        TokenizeQuotes(tok);
+                    } else if (tok->c == '^') {
+                        getTokenizerChar(tok);
+                        TokenizeCtrl(tok);
+                    } else if (tok->c == '#') {
+                        TokenizeHash(tok);
+                    } else {
+                        putTokenizerChar(tok, '\0');
+                        tok->type = TOKEN_STRING;
+                        return tok->type;
+                    }
+                }
+            case '{':
+                while (getTokenizerChar(tok) != '}')
+                    putTokenizerChar(tok, tok->c);
+                putTokenizerChar(tok, '\0');
+                tok->type = TOKEN_COMMENT;
+                getTokenizerChar(tok);
+                return tok->type;
+            case '(':
+                getTokenizerChar(tok);
+                if (tok->c  == '*') {
+                    for (;;) {
+                        if (getTokenizerChar(tok) == '*') {
+                            if (getTokenizerChar(tok) == ')') {
+                                putTokenizerChar(tok, '\0');
+                                tok->type = TOKEN_COMMENT;
+                                getTokenizerChar(tok);
+                                return tok->type;
+                            } else {
+                                putTokenizerChar(tok, '*');
+                            }
+                        }
+                        putTokenizerChar(tok, tok->c);
+                    }
+                } else {
+                    tok->type = TOKEN_CHAR;
+                    putTokenizerChar(tok, '(');
+                    putTokenizerChar(tok, '\0');
+                    return tok->type;
+                }
+            case '$':
+                putTokenizerChar(tok, '0');
+                putTokenizerChar(tok, 'x');
+                while (isxdigit(getTokenizerChar(tok))) {
+                    putTokenizerChar(tok, tok->c);
+                }
+                tok->type = TOKEN_HEX;
+                putTokenizerChar(tok, '\0');
+                return tok->type;
+            default:
+                tok->type = TOKEN_CHAR;
+                putTokenizerChar(tok, tok->c);
+                putTokenizerChar(tok, '\0');
+                getTokenizerChar(tok);
+                return tok->type;
+        }
+    }
+}

File tokenize.h

View file
+#ifndef TOKENIZE_H
+#define TOKENIZE_H
+
+#if 0
+#define TOKEN_SIZE 255
+#endif
+
+enum TOKEN_TYPE {
+    TOKEN_EOF,
+    TOKEN_CHAR,
+    TOKEN_NAME,
+    TOKEN_INT,
+    TOKEN_HEX,
+    TOKEN_REAL,
+    TOKEN_ENG,
+    TOKEN_STRING,
+    TOKEN_COMMENT,
+    TOKEN_DEFEQ,
+    TOKEN_DOTDOT,
+    TOKEN_LEQ,
+    TOKEN_GEQ,
+    TOKEN_NEQ,
+    TOKEN_ERROR,
+    MAX_TOKEN
+};
+
+struct Tokenizer {
+    char           *filename;                              /* Nazwa tokenizowanego pliku. */
+    FILE           *source;                                /* Stad beda czytane tokeny. */
+    unsigned int    c;                                     /* Ostatnio wczytany znak. */
+    enum TOKEN_TYPE type;                                  /* Rodzaj tokena. */
+#if 0
+    char            buffer[TOKEN_SIZE];                    /* Bufor na tekst tokena. */
+#endif
+    int             bufpos;                                /* Pozycja w buforze. */
+    int             line;                                  /* Aktualny numer linii. */
+    int             position;                              /* Numer kolumny. */
+    unsigned int    putback;                               /* Znak do zwrotu. */
+    GString         *buf;                                  /* String tokena. */ 
+};
+
+typedef struct Tokenizer Tokenizer;
+
+Tokenizer *newTokenizer(const char *filename);
+void destroyTokenizer(Tokenizer *tok);
+enum TOKEN_TYPE getNextToken(Tokenizer *tok);
+
+#endif /*not TOKENIZE_H*/

File tp4.output

View file
+Conflict in state 260 between rule 162 and token K_ELSE resolved as shift.
+
+
+Terminals which are not used:
+
+   ID_UNIT
+
+
+Grammar
+
+  Number, Line, Rule
+    1  83 compilation_unit -> program
+    2  87 compilation_unit -> unit
+    3  94 program -> program_heading uses_clause block '.'
+    4  98 program_heading -> /* empty */
+    5  99 program_heading -> K_PROGRAM ID_NAME ';'
+    6 100 program_heading -> K_PROGRAM ID_NAME '(' id_name_list ')' ';'
+    7 108 uses_clause -> /* empty */
+    8 109 uses_clause -> K_USES id_name_list ';'
+    9 119 id_name_list -> ID_NAME
+   10 126 id_name_list -> id_name_list ',' ID_NAME
+   11 136 block -> decl_sect_list compound_stmt
+   12 142 unit -> unit_heading interface_part implementation_part initialization_part '.'
+   13 148 unit_heading -> K_UNIT ID_NAME ';'
+   14 154 interface_part -> K_INTERFACE uses_clause int_decl_sect_list
+   15 160 implementation_part -> K_IMPLEMENTATION uses_clause decl_sect_list
+   16 166 initialization_part -> compound_stmt
+   17 169 initialization_part -> K_END
+   18 177 decl_sect_list -> /* empty */
+   19 178 decl_sect_list -> decl_sect_list decl_sect
+   20 182 decl_sect -> label_decl_sect
+   21 183 decl_sect -> const_decl_sect
+   22 184 decl_sect -> type_decl_sect
+   23 185 decl_sect -> var_decl_sect
+   24 186 decl_sect -> proc_decl
+   25 187 decl_sect -> func_decl
+   26 191 label_decl_sect -> K_LABEL label_list ';'
+   27 195 label_list -> label_decl
+   28 196 label_list -> label_list ',' label_decl
+   29 199 label -> CONST_INT
+   30 202 label -> ID_LABEL
+   31 207 label_decl -> CONST_INT
+   32 215 label_decl -> ID_NAME
+   33 222 const_decl_sect -> K_CONST const_decl
+   34 223 const_decl_sect -> const_decl_sect const_decl
+   35 227 type_decl_sect -> K_TYPE type_decl
+   36 228 type_decl_sect -> type_decl_sect type_decl
+   37 232 var_decl_sect -> K_VAR var_decl
+   38 233 var_decl_sect -> var_decl_sect var_decl
+   39 243 int_decl_sect_list -> /* empty */
+   40 244 int_decl_sect_list -> int_decl_sect_list int_decl_sect
+   41 248 int_decl_sect -> const_decl_sect
+   42 249 int_decl_sect -> type_decl_sect
+   43 250 int_decl_sect -> var_decl_sect
+   44 251 int_decl_sect -> proc_heading
+   45 255 int_decl_sect -> func_heading
+   46 264 const_decl -> ID_NAME '=' const ';'
+   47 268 const_decl -> ID_NAME ':' type '=' typed_const ';'
+   48 274 const -> unsigned_number
+   49 276 const -> sign unsigned_number
+   50 278 const -> ID_CONST
+   51 280 const -> sign ID_CONST
+   52 282 const -> CONST_STRING
+   53 287 unsigned_number -> CONST_INT
+   54 292 unsigned_number -> CONST_REAL
+   55 295 sign -> '+'
+   56 295 sign -> '-'
+   57 299 typed_const -> const
+   58 300 typed_const -> array_const
+   59 301 typed_const -> record_const
+   60 302 typed_const -> set_const
+   61 306 array_const -> '(' typed_const_list ')'
+   62 310 typed_const_list -> typed_const
+   63 311 typed_const_list -> typed_const_list ',' typed_const
+   64 315 record_const -> '(' const_field_list ')'
+   65 319 const_field_list -> const_field
+   66 320 const_field_list -> const_field_list ',' const_field
+   67 324 const_field -> ID_FIELD ':' typed_const
+   68 329 set_const -> '[' const_elem_list ']'
+   69 333 const_elem_list -> /* empty */
+   70 334 const_elem_list -> const_elem_list1
+   71 338 const_elem_list1 -> const_elem
+   72 339 const_elem_list1 -> const_elem_list1 ',' const_elem
+   73 343 const_elem -> const
+   74 344 const_elem -> const OP_DOTDOT const
+   75 350 type_decl -> ID_NAME '=' type ';'
+   76 356 type -> simple_type
+   77 357 type -> pointer_type
+   78 358 type -> structured_type
+   79 359 type -> string_type
+   80 363 simple_type -> ID_TYPE
+   81 365 simple_type -> const OP_DOTDOT const
+   82 367 simple_type -> '(' id_name_list ')'
+   83 374 pointer_type -> '^' ID_TYPE
+   84 378 structured_type -> unpacked_structured_type
+   85 379 structured_type -> K_PACKED unpacked_structured_type
+   86 383 unpacked_structured_type -> array_type
+   87 384 unpacked_structured_type -> record_type
+   88 385 unpacked_structured_type -> set_type
+   89 386 unpacked_structured_type -> file_type
+   90 390 array_type -> K_ARRAY '[' simple_type_list ']' K_OF type
+   91 394 simple_type_list -> simple_type
+   92 395 simple_type_list -> simple_type_list ',' simple_type
+   93 399 record_type -> K_RECORD field_list K_END
+   94 403 field_list -> fixed_part
+   95 404 field_list -> variant_part
+   96 405 field_list -> fixed_part ';' variant_part
+   97 409 fixed_part -> record_section
+   98 410 fixed_part -> fixed_part ';' record_section
+   99 414 record_section -> /* empty */
+  100 415 record_section -> id_name_list ':' type
+  101 422 variant_part -> K_CASE tag_field K_OF variant_list
+  102 426 tag_field -> ID_NAME
+  103 428 tag_field -> ID_NAME ':' ID_TYPE
+  104 433 variant_list -> variant
+  105 434 variant_list -> variant_list ';' variant
+  106 437 variant -> /* empty */
+  107 438 variant -> case_tag_list ':' '(' field_list ')'
+  108 442 case_tag_list -> const
+  109 443 case_tag_list -> case_tag_list ',' const
+  110 447 set_type -> K_SET K_OF simple_type
+  111 451 file_type -> K_FILE K_OF type
+  112 452 file_type -> K_FILE
+  113 456 string_type -> K_STRING
+  114 457 string_type -> K_STRING '[' const ']'
+  115 463 var_decl -> id_name_list ':' type absolute_clause ';'
+  116 473 absolute_clause -> /* empty */
+  117 474 absolute_clause -> K_ABSOLUTE CONST_INT ':' CONST_INT
+  118 475 absolute_clause -> K_ABSOLUTE ID_VAR
+  119 481 proc_decl -> proc_heading proc_block ';'
+  120 490 func_decl -> func_heading proc_block ';'
+  121 501 proc_heading_beginning -> K_PROCEDURE ID_NAME
+  122 506 proc_heading_beginning -> K_PROCEDURE ID_PROC
+  123 513 func_heading_beginning -> K_FUNCTION ID_NAME
+  124 518 func_heading_beginning -> K_FUNCTION ID_FUNC
+  125 525 proc_heading -> proc_heading_beginning fp_list ';'
+  126 529 func_heading -> func_heading_beginning fp_list ':' fptype ';'
+  127 533 proc_block -> block
+  128 534 proc_block -> K_EXTERNAL
+  129 535 proc_block -> K_FORWARD
+  130 538 fp_list -> /* empty */
+  131 539 fp_list -> '(' fp_sect_list ')'
+  132 543 fp_sect_list -> fp_sect
+  133 544 fp_sect_list -> fp_sect_list ';' fp_sect
+  134 547 fp_sect -> id_name_list ':' fptype
+  135 552 fp_sect -> K_VAR id_name_list ':' fptype
+  136 557 fp_sect -> K_VAR id_name_list
+  137 564 fptype -> ID_TYPE
+  138 566 fptype -> K_STRING
+  139 571 stmt -> unlabelled_stmt
+  140 572 stmt -> label ':' unlabelled_stmt
+  141 576 unlabelled_stmt -> /* empty */
+  142 577 unlabelled_stmt -> assignment
+  143 578 unlabelled_stmt -> proc_call
+  144 579 unlabelled_stmt -> goto_stmt
+  145 580 unlabelled_stmt -> compound_stmt
+  146 581 unlabelled_stmt -> if_stmt
+  147 582 unlabelled_stmt -> case_stmt
+  148 583 unlabelled_stmt -> repeat_stmt
+  149 584 unlabelled_stmt -> while_stmt
+  150 585 unlabelled_stmt -> for_stmt
+  151 586 unlabelled_stmt -> with_stmt
+  152 590 assignment -> variable OP_DEFEQ expr
+  153 594 proc_call -> ID_PROC param_list
+  154 599 param_list -> /* empty */
+  155 600 param_list -> '(' expr_list ')'
+  156 604 expr_list -> expr
+  157 605 expr_list -> expr_list ',' expr
+  158 609 goto_stmt -> K_GOTO label
+  159 613 compound_stmt -> K_BEGIN stmt_list K_END
+  160 617 stmt_list -> stmt
+  161 618 stmt_list -> stmt_list ';' stmt
+  162 621 if_stmt -> K_IF expr K_THEN stmt
+  163 622 if_stmt -> K_IF expr K_THEN stmt K_ELSE stmt
+  164 626 case_stmt -> K_CASE expr K_OF case_list else_case K_END
+  165 630 case_list -> case
+  166 631 case_list -> case_list ';' case
+  167 634 case -> /* empty */
+  168 635 case -> case_label_list ':' stmt
+  169 639 case_label_list -> case_label
+  170 640 case_label_list -> case_label_list ',' case_label
+  171 644 case_label -> const
+  172 645 case_label -> const OP_DOTDOT const
+  173 649 else_case -> /* empty */
+  174 650 else_case -> K_ELSE stmt
+  175 651 else_case -> K_ELSE stmt ';'
+  176 655 repeat_stmt -> K_REPEAT stmt_list K_UNTIL expr
+  177 659 while_stmt -> K_WHILE expr K_DO stmt
+  178 663 for_stmt -> K_FOR ID_VAR OP_DEFEQ expr K_TO expr K_DO stmt
+  179 664 for_stmt -> K_FOR ID_VAR OP_DEFEQ expr K_DOWNTO expr K_DO stmt
+  180 668 with_stmt -> K_WITH variable_list K_DO stmt
+  181 672 variable_list -> variable
+  182 673 variable_list -> variable_list ',' variable
+  183 679 record_variable -> variable '.'
+  184 683 variable -> ID_VAR
+  185 685 variable -> variable '[' expr_list ']'
+  186 686 variable -> record_variable ID_FIELD
+  187 687 variable -> variable '^'
+  188 688 variable -> ID_TYPE '(' variable ')'
+  189 694 expr -> simple_expr
+  190 695 expr -> simple_expr relop simple_expr
+  191 698 relop -> '='
+  192 698 relop -> OP_NEQ
+  193 698 relop -> '<'
+  194 698 relop -> '>'
+  195 698 relop -> OP_LEQ
+  196 698 relop -> OP_GEQ
+  197 698 relop -> K_IN
+  198 702 simple_expr -> term
+  199 703 simple_expr -> sign term
+  200 704 simple_expr -> simple_expr addop term
+  201 707 addop -> '+'
+  202 707 addop -> '-'
+  203 707 addop -> K_OR
+  204 707 addop -> K_XOR
+  205 710 term -> factor
+  206 711 term -> term mulop factor
+  207 714 mulop -> '*'
+  208 714 mulop -> '/'
+  209 714 mulop -> K_DIV
+  210 714 mulop -> K_MOD
+  211 714 mulop -> K_SHL
+  212 714 mulop -> K_SHR
+  213 714 mulop -> K_AND
+  214 720 factor -> variable
+  215 721 factor -> ID_CONST
+  216 723 factor -> CONST_INT
+  217 725 factor -> CONST_REAL
+  218 727 factor -> CONST_STRING
+  219 729 factor -> '[' elem_list ']'
+  220 730 factor -> K_NIL
+  221 731 factor -> '@' variable
+  222 732 factor -> '(' expr ')'
+  223 733 factor -> ID_FUNC '(' expr_list ')'
+  224 735 factor -> K_NOT factor
+  225 739 elem_list -> /* empty */
+  226 740 elem_list -> elem_list1
+  227 744 elem_list1 -> elem
+  228 745 elem_list1 -> elem_list1 ',' elem
+  229 748 elem -> expr
+  230 749 elem -> expr OP_DOTDOT expr
+
+
+Terminals, with rules where they appear
+
+$ (-1)
+'(' (40) 6 61 64 82 107 131 155 188 222 223
+')' (41) 6 61 64 82 107 131 155 188 222 223
+'*' (42) 207
+'+' (43) 55 201
+',' (44) 10 28 63 66 72 92 109 157 170 182 228
+'-' (45) 56 202
+'.' (46) 3 12 183
+'/' (47) 208
+':' (58) 47 67 100 103 107 115 117 126 134 135 140 168
+';' (59) 5 6 8 13 26 46 47 75 96 98 105 115 119 120 125 126 133 161
+    166 175
+'<' (60) 193
+'=' (61) 46 47 75 191
+'>' (62) 194
+'@' (64) 221
+'[' (91) 68 90 114 185 219
+']' (93) 68 90 114 185 219
+'^' (94) 83 187
+error (256)
+K_AND (257) 213
+K_ABSOLUTE (258) 117 118
+K_ARRAY (259) 90
+K_BEGIN (260) 159
+K_CASE (261) 101 164
+K_CONST (262) 33
+K_DIV (263) 209
+K_DOWNTO (264) 179
+K_DO (265) 177 178 179 180
+K_ELSE (266) 163 174 175
+K_END (267) 17 93 159 164
+K_EXTERNAL (268) 128
+K_FILE (269) 111 112
+K_FORWARD (270) 129
+K_FOR (271) 178 179
+K_FUNCTION (272) 123 124
+K_GOTO (273) 158
+K_IF (274) 162 163
+K_IMPLEMENTATION (275) 15
+K_INTERFACE (276) 14
+K_IN (277) 197
+K_LABEL (278) 26
+K_MOD (279) 210
+K_NIL (280) 220
+K_NOT (281) 224
+K_OF (282) 90 101 110 111 164
+K_OR (283) 203
+K_PACKED (284) 85
+K_PROCEDURE (285) 121 122
+K_PROGRAM (286) 5 6
+K_RECORD (287) 93
+K_REPEAT (288) 176
+K_SET (289) 110
+K_SHL (290) 211
+K_SHR (291) 212
+K_STRING (292) 113 114 138
+K_THEN (293) 162 163
+K_TO (294) 178
+K_TYPE (295) 35
+K_UNIT (296) 13
+K_UNTIL (297) 176
+K_USES (298) 8
+K_VAR (299) 37 135 136
+K_WHILE (300) 177
+K_WITH (301) 180
+K_XOR (302) 204
+OP_DOTDOT (303) 74 81 172 230
+OP_DEFEQ (304) 152 178 179
+OP_LEQ (305) 195
+OP_NEQ (306) 192
+OP_GEQ (307) 196
+ID_FUNC (308) 124 223
+ID_PROC (309) 122 153
+ID_VAR (310) 118 178 179 184
+ID_TYPE (311) 80 83 103 137 188
+ID_LABEL (312) 30
+ID_UNIT (313)
+ID_CONST (314) 50 51 215
+ID_FIELD (315) 67 186
+ID_NAME (316) 5 6 9 10 13 32 46 47 75 102 103 121 123
+CONST_INT (317) 29 31 53 117 216
+CONST_REAL (318) 54 217
+CONST_STRING (319) 52 218
+
+
+Nonterminals, with rules where they appear
+
+compilation_unit (83)
+    on left: 1 2
+program (84)
+    on left: 3, on right: 1
+program_heading (85)
+    on left: 4 5 6, on right: 3
+uses_clause (86)
+    on left: 7 8, on right: 3 14 15
+id_name_list (87)
+    on left: 9 10, on right: 6 8 10 82 100 115 134 135 136
+block (88)
+    on left: 11, on right: 3 127
+unit (89)
+    on left: 12, on right: 2
+unit_heading (90)
+    on left: 13, on right: 12
+interface_part (91)
+    on left: 14, on right: 12
+implementation_part (92)
+    on left: 15, on right: 12
+initialization_part (93)
+    on left: 16 17, on right: 12
+decl_sect_list (94)
+    on left: 18 19, on right: 11 15 19
+decl_sect (95)
+    on left: 20 21 22 23 24 25, on right: 19
+label_decl_sect (96)
+    on left: 26, on right: 20
+label_list (97)
+    on left: 27 28, on right: 26 28
+label (98)
+    on left: 29 30, on right: 140 158
+label_decl (99)
+    on left: 31 32, on right: 27 28
+const_decl_sect (100)
+    on left: 33 34, on right: 21 34 41
+type_decl_sect (101)
+    on left: 35 36, on right: 22 36 42
+var_decl_sect (102)
+    on left: 37 38, on right: 23 38 43
+int_decl_sect_list (103)
+    on left: 39 40, on right: 14 40
+int_decl_sect (104)
+    on left: 41 42 43 44 45, on right: 40
+const_decl (105)
+    on left: 46 47, on right: 33 34
+const (106)
+    on left: 48 49 50 51 52, on right: 46 57 73 74 81 108 109 114 171
+    172
+unsigned_number (107)
+    on left: 53 54, on right: 48 49
+sign (108)
+    on left: 55 56, on right: 49 51 199
+typed_const (109)
+    on left: 57 58 59 60, on right: 47 62 63 67
+array_const (110)
+    on left: 61, on right: 58
+typed_const_list (111)
+    on left: 62 63, on right: 61 63
+record_const (112)
+    on left: 64, on right: 59
+const_field_list (113)
+    on left: 65 66, on right: 64 66
+const_field (114)
+    on left: 67, on right: 65 66
+set_const (115)
+    on left: 68, on right: 60
+const_elem_list (116)
+    on left: 69 70, on right: 68
+const_elem_list1 (117)
+    on left: 71 72, on right: 70 72
+const_elem (118)
+    on left: 73 74, on right: 71 72
+type_decl (119)
+    on left: 75, on right: 35 36
+type (120)
+    on left: 76 77 78 79, on right: 47 75 90 100 111 115
+simple_type (121)
+    on left: 80 81 82, on right: 76 91 92 110
+pointer_type (122)
+    on left: 83, on right: 77
+structured_type (123)
+    on left: 84 85, on right: 78
+unpacked_structured_type (124)
+    on left: 86 87 88 89, on right: 84 85
+array_type (125)
+    on left: 90, on right: 86
+simple_type_list (126)
+    on left: 91 92, on right: 90 92
+record_type (127)
+    on left: 93, on right: 87
+field_list (128)
+    on left: 94 95 96, on right: 93 107
+fixed_part (129)
+    on left: 97 98, on right: 94 96 98
+record_section (130)
+    on left: 99 100, on right: 97 98
+variant_part (131)
+    on left: 101, on right: 95 96
+tag_field (132)
+    on left: 102 103, on right: 101
+variant_list (133)
+    on left: 104 105, on right: 101 105
+variant (134)
+    on left: 106 107, on right: 104 105
+case_tag_list (135)
+    on left: 108 109, on right: 107 109
+set_type (136)
+    on left: 110, on right: 88
+file_type (137)
+    on left: 111 112, on right: 89
+string_type (138)
+    on left: 113 114, on right: 79
+var_decl (139)
+    on left: 115, on right: 37 38
+absolute_clause (140)
+    on left: 116 117 118, on right: 115
+proc_decl (141)
+    on left: 119, on right: 24
+func_decl (142)
+    on left: 120, on right: 25
+proc_heading_beginning (143)
+    on left: 121 122, on right: 125
+func_heading_beginning (144)
+    on left: 123 124, on right: 126
+proc_heading (145)
+    on left: 125, on right: 44 119
+func_heading (146)
+    on left: 126, on right: 45 120
+proc_block (147)
+    on left: 127 128 129, on right: 119 120
+fp_list (148)
+    on left: 130 131, on right: 125 126
+fp_sect_list (149)
+    on left: 132 133, on right: 131 133
+fp_sect (150)
+    on left: 134 135 136, on right: 132 133
+fptype (151)
+    on left: 137 138, on right: 126 134 135
+stmt (152)
+    on left: 139 140, on right: 160 161 162 163 168 174 175 177 178
+    179 180
+unlabelled_stmt (153)
+    on left: 141 142 143 144 145 146 147 148 149 150 151,
+    on right: 139 140
+assignment (154)
+    on left: 152, on right: 142
+proc_call (155)
+    on left: 153, on right: 143
+param_list (156)
+    on left: 154 155, on right: 153
+expr_list (157)
+    on left: 156 157, on right: 155 157 185 223
+goto_stmt (158)
+    on left: 158, on right: 144
+compound_stmt (159)
+    on left: 159, on right: 11 16 145
+stmt_list (160)
+    on left: 160 161, on right: 159 161 176
+if_stmt (161)
+    on left: 162 163, on right: 146
+case_stmt (162)
+    on left: 164, on right: 147
+case_list (163)
+    on left: 165 166, on right: 164 166
+case (164)
+    on left: 167 168, on right: 165 166
+case_label_list (165)
+    on left: 169 170, on right: 168 170
+case_label (166)
+    on left: 171 172, on right: 169 170
+else_case (167)
+    on left: 173 174 175, on right: 164
+repeat_stmt (168)
+    on left: 176, on right: 148
+while_stmt (169)
+    on left: 177, on right: 149
+for_stmt (170)
+    on left: 178 179, on right: 150
+with_stmt (171)
+    on left: 180, on right: 151
+variable_list (172)
+    on left: 181 182, on right: 180 182
+record_variable (173)
+    on left: 183, on right: 186
+variable (174)
+    on left: 184 185 186 187 188, on right: 152 181 182 183 185 187
+    188 214 221
+expr (175)
+    on left: 189 190, on right: 152 156 157 162 163 164 176 177 178
+    179 222 229 230
+relop (176)
+    on left: 191 192 193 194 195 196 197, on right: 190
+simple_expr (177)
+    on left: 198 199 200, on right: 189 190 200
+addop (178)
+    on left: 201 202 203 204, on right: 200
+term (179)
+    on left: 205 206, on right: 198 199 200 206
+mulop (180)
+    on left: 207 208 209 210 211 212 213, on right: 206
+factor (181)
+    on left: 214 215 216 217 218 219 220 221 222 223 224,
+    on right: 205 206 224
+elem_list (182)
+    on left: 225 226, on right: 219
+elem_list1 (183)
+    on left: 227 228, on right: 226 228
+elem (184)
+    on left: 229 230, on right: 227 228
+
+
+state 0
+
+    K_PROGRAM	shift, and go to state 1
+    K_UNIT	shift, and go to state 2
+
+    $default	reduce using rule 4 (program_heading)
+
+    compilation_unit	go to state 393
+    program	go to state 3
+    program_heading	go to state 4
+    unit	go to state 5
+    unit_heading	go to state 6
+
+
+
+state 1
+
+    program_heading  ->  K_PROGRAM . ID_NAME ';'   (rule 5)
+    program_heading  ->  K_PROGRAM . ID_NAME '(' id_name_list ')' ';'   (rule 6)
+
+    ID_NAME	shift, and go to state 7
+
+
+
+state 2
+
+    unit_heading  ->  K_UNIT . ID_NAME ';'   (rule 13)
+
+    ID_NAME	shift, and go to state 8
+
+
+
+state 3
+
+    compilation_unit  ->  program .   (rule 1)
+
+    $default	reduce using rule 1 (compilation_unit)
+
+
+
+state 4
+
+    program  ->  program_heading . uses_clause block '.'   (rule 3)
+
+    K_USES	shift, and go to state 9
+
+    $default	reduce using rule 7 (uses_clause)
+
+    uses_clause	go to state 10
+
+
+
+state 5
+
+    compilation_unit  ->  unit .   (rule 2)
+
+    $default	reduce using rule 2 (compilation_unit)
+
+
+
+state 6
+
+    unit  ->  unit_heading . interface_part implementation_part initialization_part '.'   (rule 12)
+
+    K_INTERFACE	shift, and go to state 11
+
+    interface_part	go to state 12
+
+
+
+state 7
+
+    program_heading  ->  K_PROGRAM ID_NAME . ';'   (rule 5)
+    program_heading  ->  K_PROGRAM ID_NAME . '(' id_name_list ')' ';'   (rule 6)
+
+    ';' 	shift, and go to state 13
+    '(' 	shift, and go to state 14
+
+
+
+state 8
+
+    unit_heading  ->  K_UNIT ID_NAME . ';'   (rule 13)
+
+    ';' 	shift, and go to state 15
+
+
+
+state 9
+
+    uses_clause  ->  K_USES . id_name_list ';'   (rule 8)
+
+    ID_NAME	shift, and go to state 16
+
+    id_name_list	go to state 17
+
+
+
+state 10
+
+    program  ->  program_heading uses_clause . block '.'   (rule 3)
+
+    $default	reduce using rule 18 (decl_sect_list)
+
+    block	go to state 18
+    decl_sect_list	go to state 19
+
+
+
+state 11
+
+    interface_part  ->  K_INTERFACE . uses_clause int_decl_sect_list   (rule 14)
+
+    K_USES	shift, and go to state 9
+
+    $default	reduce using rule 7 (uses_clause)
+
+    uses_clause	go to state 20
+
+
+
+state 12
+
+    unit  ->  unit_heading interface_part . implementation_part initialization_part '.'   (rule 12)
+
+    K_IMPLEMENTATION	shift, and go to state 21
+
+    implementation_part	go to state 22
+
+
+
+state 13
+
+    program_heading  ->  K_PROGRAM ID_NAME ';' .   (rule 5)
+
+    $default	reduce using rule 5 (program_heading)
+
+
+
+state 14
+
+    program_heading  ->  K_PROGRAM ID_NAME '(' . id_name_list ')' ';'   (rule 6)
+
+    ID_NAME	shift, and go to state 16
+
+    id_name_list	go to state 23
+
+
+
+state 15
+
+    unit_heading  ->  K_UNIT ID_NAME ';' .   (rule 13)
+
+    $default	reduce using rule 13 (unit_heading)
+
+
+
+state 16
+
+    id_name_list  ->  ID_NAME .   (rule 9)
+
+    $default	reduce using rule 9 (id_name_list)
+
+
+
+state 17