From ced3820e8e14b96eb1a6da8f30d1e529b8c48a0d Mon Sep 17 00:00:00 2001 From: setanta Date: Tue, 18 Dec 2007 00:55:37 +0000 Subject: [PATCH] Inicializando repositorio. git-svn-id: https://toypasc.googlecode.com/svn/trunk@2 cbd757d2-8441-0410-81db-47b75ec2d254 --- Makefile | 33 ++++++++ ast.c | 38 +++++++++ ast.h | 18 +++++ base.h | 8 ++ lextest.l | 28 +++++++ parser.y | 249 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ sample.pas | 17 ++++ scanner.l | 56 +++++++++++++ symbol_table.c | 33 ++++++++ symbol_table.h | 24 ++++++ 10 files changed, 504 insertions(+) create mode 100755 Makefile create mode 100755 ast.c create mode 100755 ast.h create mode 100755 base.h create mode 100755 lextest.l create mode 100755 parser.y create mode 100755 sample.pas create mode 100755 scanner.l create mode 100755 symbol_table.c create mode 100755 symbol_table.h diff --git a/Makefile b/Makefile new file mode 100755 index 0000000..c010c79 --- /dev/null +++ b/Makefile @@ -0,0 +1,33 @@ +LEX=flex +YACC=bison +CC=gcc +CFLAGS=-ggdb +LIBS= +PARSER=parser +SCANNER=scanner +OBJS=$(SCANNER).o $(PARSER).o symbol_table.o ast.o +PROGRAM=plminus + +all: $(OBJS) + $(CC) $(LIBS) $(OBJS) -o $(PROGRAM) + +symbol_table.o: symbol_table.c symbol_table.h + $(CC) $(CFLAGS) symbol_table.c -c + +ast.o: ast.c ast.h + $(CC) $(CFLAGS) ast.c -c + +$(PARSER).o: $(PARSER).c $(PARSER).h + $(CC) $(CFLAGS) $(PARSER).c -c + +$(SCANNER).o: $(SCANNER).c $(PARSER).h + $(CC) $(CFLAGS) $(SCANNER).c -c + +$(SCANNER).c: $(SCANNER).l + $(LEX) -o$(SCANNER).c $(SCANNER).l + +$(PARSER).h: $(PARSER).y + $(YACC) -d $(PARSER).y -o $(PARSER).c + +clean: + rm -rf $(SCANNER).c $(PARSER).c $(PARSER).h *.o $(PROGRAM) diff --git a/ast.c b/ast.c new file mode 100755 index 0000000..a3a884a --- /dev/null +++ b/ast.c @@ -0,0 +1,38 @@ +#include +#include "ast.h" + +AstNode * +ast_node_new(int kind, int type, int linenum, Symbol *symbol) +{ + int i; + AstNode *node; + + node = (AstNode *) malloc (sizeof(AstNode)); + + node->kind = kind; + node->type = type; + node->linenum = linenum; + node->symbol = symbol; + + for (i = 0; i < 3; i++) + node->children[i] = NULL; + node->next = NULL; + + return node; +} + +void +ast_node_destroy(AstNode *node) +{ + int i; + + if (node == NULL) + return; + + for (i = 0; i < 3; i++) + ast_node_destroy(node->children[i]); + ast_node_destroy(node->next); + + free(node); +} + diff --git a/ast.h b/ast.h new file mode 100755 index 0000000..6973fda --- /dev/null +++ b/ast.h @@ -0,0 +1,18 @@ +#ifndef AST_H +#define AST_H + +#include "symbol_table.h" + +typedef struct _AstNode { + int kind; + int type; + int linenum; + Symbol *symbol; + struct _AstNode* children[3]; + struct _AstNode* next; +} AstNode; + +AstNode *ast_node_new(int kind, int type, int linenum, Symbol *symbol); +void ast_node_destroy(AstNode *node); + +#endif // AST_H diff --git a/base.h b/base.h new file mode 100755 index 0000000..6d3faef --- /dev/null +++ b/base.h @@ -0,0 +1,8 @@ +#ifndef BASE_H +#define BASE_H + +#define TRUE 1 +#define FALSE 0 + +#endif // BASE_H + diff --git a/lextest.l b/lextest.l new file mode 100755 index 0000000..9966886 --- /dev/null +++ b/lextest.l @@ -0,0 +1,28 @@ +%{ +#include +%} + +%% +"Integer" printf("T_INTEGER "); +"Var" printf("T_VAR "); +"Begin" printf("T_BEGIN "); +"End" printf("T_END "); +"Procedure" printf("T_PROCEDURE "); +"Function" printf("T_FUNCTION "); + +"*" printf("T_MULT "); +"/" printf("T_DIV "); +"+" printf("T_ADD "); +"-" printf("T_SUB "); +":=" printf("T_ATTRIBUTION "); +";" printf("T_SEMICOLON "); +":" printf("T_COLON "); +"." printf("T_DOT "); + +[0-9]+ printf("NUMBER "); +[A-Za-z][A-Za-z0-9]* printf("IDENTIFIER "); + +[ \t]+ /* ignora whitespace */; +\n printf("\n"); +%% + diff --git a/parser.y b/parser.y new file mode 100755 index 0000000..1528727 --- /dev/null +++ b/parser.y @@ -0,0 +1,249 @@ +%{ +#include +#include +#include "parser.h" +#include "base.h" +#include "ast.h" +#include "symbol_table.h" + +/*extern char *yytext;*/ +extern FILE *yyin; + +static void yyerror (/*YYLTYPE *locp, */const char *msg); +/*int yylex (YYSTYPE *yylval_param, YYLTYPE *yylloc_param);*/ + +%} + +%defines +%locations +%pure-parser +%error-verbose +/*%parse-param {ValaParser *parser} +%lex-param {ValaParser *parser}*/ + +%union { + char* lexeme; + int integer; + int boolean; +} + +%token T_INTEGER +%token T_BOOLEAN + +%token T_VAR +%token T_BEGIN +%token T_END +%token T_PROCEDURE +%token T_FUNCTION + +%token T_PRINT_INT +%token T_PRINT_BOOL +%token T_PRINT_LINE + +%token T_ASSIGNMENT + +%token T_ADD +%token T_SUB +%token T_DIV +%token T_MULT + +%token T_MAJOR +%token T_MINOR +%token T_EQUAL +%token T_NOTEQUAL +%token T_MAJOREQUAL +%token T_MINOREQUAL + +%token T_LPAR +%token T_RPAR +%token T_SEMICOLON +%token T_COLON +%token T_COMMA +%token T_DOT + +%token IDENTIFIER +%token NUMBER +%token BOOLEAN + +/*%type program +%type var_decl_list +%type var_decl +%type var_type +%type proc_func_list +%type proc_func_decl +%type proc_func_body +%type proc_decl +%type func_decl +%type param_list +%type single_param +%type multi_param +%type code_block +%type statements +%type statement*/ + +%type assignment +%type numeric_expression +%type relational_expression +%type number_literal + +/*%type print_statement +%type print_integer +%type print_boolean +%type print_line*/ + +%start program + +%% +program: + var_decl_list proc_func_list code_block T_DOT { printf("program\n"); } + ; + +var_decl_list: + var_decl_list var_decl { printf("\n"); } + | /* empty */ + ; + +var_decl: + T_VAR IDENTIFIER T_COLON var_type T_SEMICOLON + { printf("var_decl\n") } + ; + +var_type: + T_INTEGER + { printf("var_type\n") } + | T_BOOLEAN + { printf("var_type\n") } + ; + +proc_func_list: + /* empty */ + { printf("proc_func_list\n") } + | proc_func_list proc_decl + { printf("proc_func_list\n") } + | proc_func_list func_decl + { printf("proc_func_list\n") } + ; + +proc_func_decl: + IDENTIFIER T_LPAR param_list T_RPAR + { printf("proc_func_decl\n") } + ; + +proc_func_body: + var_decl_list code_block T_SEMICOLON + { printf("proc_func_body\n") } + ; + +proc_decl: + T_PROCEDURE proc_func_decl T_SEMICOLON proc_func_body + { printf("proc_decl\n") } + ; + +func_decl: + T_FUNCTION proc_func_decl T_COLON var_type T_SEMICOLON proc_func_body + { printf("func_decl\n") } + ; + +param_list: + /* empty */ + { printf("param_list\n") } + | single_param multi_param + { printf("param_list\n") } + ; + +single_param: + IDENTIFIER T_COLON var_type + { printf("single_param\n") } + ; + +multi_param: + /* empty */ + { printf("multi_param\n") } + | T_COMMA single_param multi_param + { printf("multi_param\n") } + ; + +code_block: + T_BEGIN statements T_END + { printf("code_block\n") } + ; + +statements: + /* empty */ + | statements statement T_SEMICOLON + ; + +statement: + assignment + | print_statement + ; + +assignment: + IDENTIFIER T_ASSIGNMENT expression + | IDENTIFIER T_ASSIGNMENT NUMBER { $$ = $1; } + ; + +expression: + numeric_expression + | relational_expression + ; + +numeric_expression: + numeric_expression T_ADD numeric_expression { $$ = $1 + $3; } + | numeric_expression T_SUB numeric_expression { $$ = $1 - $3; } + | number_literal { $$ = $1; } + ; + +number_literal: + NUMBER { $$ = $1; } + ; + +relational_expression: + numeric_expression relational_operator numeric_expression + ; + +relational_operator: + T_MINOR + | T_MINOREQUAL + | T_MAJOR + | T_MAJOREQUAL + | T_EQUAL + | T_NOTEQUAL + ; + +print_statement: + print_integer + | print_boolean + | print_line + ; + +print_integer: + T_PRINT_INT T_LPAR NUMBER T_RPAR { printf ("%d", $3); } + +print_boolean: + T_PRINT_BOOL T_LPAR BOOLEAN T_RPAR { printf ("%s", ($3 == 0 ? "False" : "True")); } + +print_line: + T_PRINT_LINE T_LPAR T_RPAR { printf ("\n"); } +%% + +static void +yyerror (/*YYLTYPE *locp,*/ const char *msg) +{ + fprintf(stderr,"error: %s\n", msg); +} + +int +main(int argc, char **argv) +{ + if (argc > 1) + yyin = fopen(argv[1], "r"); + else + yyin = stdin; + + /*yylloc.first_line = yylloc.last_line = 1; + yylloc.first_column = yylloc.last_column = 0;*/ + + return yyparse(); +} + diff --git a/sample.pas b/sample.pas new file mode 100755 index 0000000..c8332c7 --- /dev/null +++ b/sample.pas @@ -0,0 +1,17 @@ +Var x : Integer; +Var y: Integer; + +Procedure teste (a : Integer); +Var i : Integer; +Begin + printInt(666); + println(); +End; + +Begin + x := 10; + x := 7 - 1; + printInt(11); + println(); + printInt(22); +End. diff --git a/scanner.l b/scanner.l new file mode 100755 index 0000000..a86f10f --- /dev/null +++ b/scanner.l @@ -0,0 +1,56 @@ +%{ +#include +#include "parser.h" + +#define uploc { yylloc->first_column = yylloc->last_column + 1; yylloc->last_column += yyleng; } +/*#define YY_DECL int yylex (YYSTYPE *yylval_param)*/ +%} + +%option yylineno +%option bison-bridge +%option bison-locations +%option noyywrap +%option nounput + +%% +"Integer" { uploc; return T_INTEGER; } +"Var" { uploc; return T_VAR; } +"Begin" { uploc; return T_BEGIN; } +"End" { uploc; return T_END; } + +"Procedure" { uploc; return T_PROCEDURE; } +"Function" { uploc; return T_FUNCTION; } + +"printInt" { uploc; return T_PRINT_INT; } +"printBoolean" { uploc; return T_PRINT_BOOL; } +"println" { uploc; return T_PRINT_LINE; } + +":=" { uploc; return T_ASSIGNMENT; } +"(" { uploc; return T_LPAR; } +")" { uploc; return T_RPAR; } +"+" { uploc; return T_ADD; } +"-" { uploc; return T_SUB; } +"*" { uploc; return T_MULT; } +"/" { uploc; return T_DIV; } + +">" { uploc; return T_MAJOR; } +"<" { uploc; return T_MINOR; } +"=" { uploc; return T_EQUAL; } +"<>" { uploc; return T_NOTEQUAL; } +">=" { uploc; return T_MAJOREQUAL; } +"<=" { uploc; return T_MINOREQUAL; } + +";" { uploc; return T_SEMICOLON; } +":" { uploc; return T_COLON; } +"." { uploc; return T_DOT; } +"," { uploc; return T_COMMA; } + +"True"|"False" { uploc; yylval->boolean=strcmp(yytext, "False"); return BOOLEAN; } +[0-9]+ { uploc; yylval->integer=atoi(yytext); return NUMBER; } +[A-Za-z][A-Za-z0-9]* { uploc; yylval->lexeme=strdup(yytext); return IDENTIFIER; } + +[ \t]+ /* ignora whitespace */; +[ \n] { yylloc->first_line = yylloc->last_line = yylineno; yylloc->first_column = 1; yylloc->last_column = 0; } + +. { uploc; fprintf (stderr, "%d: syntax error: unexpected character ´%s´\n", yylloc->first_line, yytext); } +%% diff --git a/symbol_table.c b/symbol_table.c new file mode 100755 index 0000000..42ebd94 --- /dev/null +++ b/symbol_table.c @@ -0,0 +1,33 @@ +#include "symbol_table.h" + +Symbol * +symbol_table_new(void) +{ +} + +void +symbol_table_destroy(void) +{ +} + +char * +symbol_table_dump(void) +{ +} + +Symbol * +symbol_insert(char const * name, int type) +{ +} + +Symbol * +symbol_lookup(char const * name) +{ +} + +int +symbol_exists(char const * name) +{ +} + + diff --git a/symbol_table.h b/symbol_table.h new file mode 100755 index 0000000..d61866d --- /dev/null +++ b/symbol_table.h @@ -0,0 +1,24 @@ +#ifndef SYMBOL_TABLE_H +#define SYMBOL_TABLE_H + +typedef struct _symbol { + char *name; + int type; + + union { + int integer; + int boolean; + char character; + } value; + + struct _symbol *next; +} Symbol; + +Symbol *symbol_table_new(void); +void symbol_table_destroy(void); +char *symbol_table_dump(void); +Symbol *symbol_insert(char const * name, int type); +Symbol *symbol_lookup(char const * name); +int symbol_exists(char const * name); + +#endif // SYMBOL_TABLE_H -- 2.11.4.GIT