📄 gbc_read.c
字号:
/*************************************************************************** read.c Lexical parser (c) 2000-2004 Beno顃 Minisini <gambas@users.sourceforge.net> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.***************************************************************************/#define _READ_C#include <stdlib.h>#include <string.h>#include <strings.h>#include <stdio.h>#include <ctype.h>#include <sys/stat.h>#include <sys/types.h>#include <sys/time.h>#include <dirent.h>#include "gb_common.h"#include "gb_error.h"#include "gb_table.h"#include "gb_file.h"#include "gbc_compile.h"#include "gbc_class.h"#include "gbc_read.h"/*#define DEBUG*/PRIVATE boolean is_init = FALSE;PRIVATE COMPILE *comp;PRIVATE long source_ptr;PRIVATE int last_pattern_type = -1;PRIVATE PATTERN last_pattern = 0;PRIVATE boolean begin_line = FALSE;PRIVATE void READ_init(void){ JOB->line = 1;}/* We declare the well known class to the compiler. See trans_expr.c */#if 0PRIVATE void READ_exit(void){ static const char *wkclass[] = { "gb", "Class", "File", "Error", "Application", "System", "Collection", "Process", "Component", "Components", "Object", "Class", NULL }; long index; const char **wkc; FILE *file; char buffer[256]; int len; DIR *dir; struct dirent *dirent; const char *name; for (wkc = wkclass; *wkc; wkc++) { if (TABLE_find_symbol(JOB->class->table, *wkc, strlen(*wkc), NULL, &index)) CLASS_add_class(JOB->class, index); } if (JOB->class_file) { file = fopen(JOB->class_file, "r"); if (file) { for(;;) { if (!fgets(buffer, sizeof(buffer), file)) break; len = strlen(buffer); if (len > 0 && buffer[len - 1] == '\n') len--; if (len == 0) continue; if (TABLE_find_symbol(JOB->class->table, buffer, len, NULL, &index)) CLASS_add_class(JOB->class, index); } fclose(file); } else THROW("Cannot open file: &1", JOB->class_file); } else { dir = opendir(FILE_get_dir(COMP_project)); if (dir) { while ((dirent = readdir(dir)) != NULL) { name = dirent->d_name; if (*name == '.') continue; if ((strcasecmp(FILE_get_ext(name), ".module") == 0) || (strcasecmp(FILE_get_ext(name), ".class") == 0)) { name = FILE_get_basename(name); if (TABLE_find_symbol(JOB->class->table, name, strlen(name), NULL, &index)) CLASS_add_class(JOB->class, index); } } closedir(dir); } }}#endifPRIVATE void READ_exit(void){ char *p, *p2; long index; p = COMP_classes; for(;;) { p2 = strchr(p, '\n'); if (p2 == p) break; if (TABLE_find_symbol(JOB->class->table, p, p2 - p, NULL, &index)) CLASS_add_class(JOB->class, index); p = p2 + 1; }}PUBLIC void READ_dump_pattern(PATTERN *pattern){ int type = PATTERN_type(*pattern); long index = PATTERN_index(*pattern); long pos; pos = (long)(pattern - JOB->pattern); if (pos >= 0 && pos < ARRAY_count(JOB->pattern)) printf("%ld ", pos); if (PATTERN_flag(*pattern) & RT_FIRST) printf("!"); else printf(" "); if (PATTERN_flag(*pattern) & RT_POINT) printf("."); else printf(" "); printf(" "); if (type == RT_RESERVED) printf("RESERVED %s\n", TABLE_get_symbol_name(COMP_res_table, index)); else if (type == RT_NUMBER) printf("NUMBER %s\n", TABLE_get_symbol_name(JOB->class->table, index)); else if (type == RT_IDENTIFIER) printf("IDENTIFIER %s\n", TABLE_get_symbol_name(JOB->class->table, index)); else if (type == RT_STRING) printf("STRING %s\n", TABLE_get_symbol_name(JOB->class->string, index)); else if (type == RT_TSTRING) printf("TSTRING %s\n", TABLE_get_symbol_name(JOB->class->string, index)); else if (type == RT_NEWLINE) printf("NEWLINE (%ld)\n", index); else if (type == RT_END) printf("END\n"); else if (type == RT_PARAM) printf("PARAM %ld\n", index); else if (type == RT_SUBR) printf("SUBR %s\n", COMP_subr_info[index].name); else printf("? %ld\n", index);}PRIVATE unsigned char get_char_offset(int offset){ offset += source_ptr; if (offset >= BUFFER_length(comp->source) || offset < 0) return 0; else return (unsigned char)(comp->source[offset]);}PRIVATE unsigned char get_char(void){ return get_char_offset(0);}PRIVATE unsigned char next_char(void){ source_ptr++; return get_char();}PRIVATE void add_pattern(int type, long index){ PATTERN *pattern; /* if (index > 100) THROW("add_pattern", "Too many words."); */ pattern = ARRAY_add(&comp->pattern); *pattern = PATTERN_make(type, index); last_pattern_type = type; last_pattern = *pattern; #ifdef DEBUG READ_dump_pattern(pattern); #endif}PRIVATE void add_newline(){ add_pattern(RT_NEWLINE, comp->line); /*source_ptr++;*/ comp->line++;}PRIVATE void add_end(){ add_pattern(RT_END, 0); /*source_ptr++;*/ comp->line++;}PRIVATE bool is_number(){ int pos = 0; unsigned char car; unsigned char car2; car = get_char_offset(pos); if (car == '-' || car == '+') { car = get_char_offset(-1); if (car && !isspace(car)) return FALSE; pos++; car = get_char_offset(pos); } if (isdigit(car)) return TRUE; car2 = toupper(get_char_offset(pos + 1)); if (car == '&') { if (car2 == 'H') { pos += 2; goto __HEX; } if (car2 == 'X') { pos += 2; goto __BIN; } pos++; goto __HEX; } else if (car == '%') { pos ++; goto __BIN; } else return FALSE; __HEX: car = get_char_offset(pos); return (isdigit(car) || index("abcdefABCDEF", car) != NULL); __BIN: car = get_char_offset(pos); return (car == '0' || car == '1');}PRIVATE void add_number(){ unsigned char car; long start; long index; start = source_ptr; car = get_char(); if (car == '-' || car == '+') car = next_char(); if (car == '&') { car = toupper(next_char()); if (car == 'H') goto READ_HEXA; else if (car == 'X') goto READ_BINARY; else { source_ptr--; goto READ_HEXA; } } else if (car == '%') goto READ_BINARY; else goto READ_NUMBER;READ_BINARY: for (;;) { car = next_char(); if (car != '0' && car != '1') break; } if (car == '&') car = next_char(); goto END;READ_HEXA: for (;;) { car = next_char(); if (!isxdigit(car)) break; } if (car == '&') car = next_char(); goto END;READ_NUMBER: while (isdigit(car)) car = next_char(); if (car == '.') { do { car = next_char(); } while (isdigit(car)); } if (toupper(car) == 'E') { car = next_char(); if (car == '+' || car == '-') car = next_char(); while (isdigit(car)) car = next_char(); } goto END;END: TABLE_add_symbol(comp->class->table, &comp->source[start], source_ptr - start, NULL, &index); add_pattern(RT_NUMBER, index);}PRIVATE void add_identifier(bool no_res){ unsigned char car; long start; int len; long index; int type; boolean not_first; boolean can_be_reserved; boolean can_be_subr; boolean is_type; boolean last_func, last_declare, last_type; start = source_ptr; len = 1; for(;;) { source_ptr++; car = get_char(); if (car == 0 || ((!isalnum(car)) && (strchr("$_?", (int)car) == NULL))) break; len++; } if (no_res) { if (get_char() == '}') source_ptr++; goto IDENTIFIER; } /* On peut mettre ':' dans un identifieur,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -