home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
- CALLEX.C
- (C) ¬⌐┼v 1988-1992 Autodesk ñ╜Ñq
-
- Ñ╗╡{ªíñwÑ╤ Autodesk ñ╜Ñq╡∙ÑU¬⌐┼v, ╢╚⌐≤ñU¡z▒í¬pñUÑi▒┬╗P▒zíu│\ÑiívíC
- ╗╒ñUñú▒oÑHÑ⌠ª≤º╬ªí╡oªµ⌐╬ÑX¬⌐ª╣╡{ªí¬║íu¡∞⌐l╜Xív; ª²ñ╣│\▒zªb»S⌐w¡lÑ═
- ¬║ñuº@ñW╡▓ªXª╣╡{ªí¬║íuÑ╪¬║╜Xív¿╧Ñ╬íCª│├÷│o├■¡lÑ═ñuº@¬║▒°Ñ≤ªpñU:
-
- ( i) │]¡pñW╗Pñuº@ñW¼╥»┬║Θ░w╣∩ Autodesk ñ╜Ñq¬║▓ú½~íC
- (ii) ╕ⁿª│íu¬⌐┼v (C) 1988-1992 Autodesk ñ╜Ñqív¬║¬⌐┼v│qºiíC
-
-
-
- AUTODESKñ╜Ñq┤ú¿╤ª╣╡{ªí╢╚¿╤º@íu├■ªⁿív¬║░╤ª╥, ª╙ÑBñú▒╞░úª│Ñ⌠ª≤┐∙╗~¬║
- Ñi»αíCAUTODESKñ╜Ñq»Sª╣º_╗{Ñ⌠ª≤»S⌐wÑ╬│~ñº╛A║┘⌐╩, ÑHñ╬░╙╖~╛P░Γ⌐╥┴⌠ºt
- ÑX¿π¬║½O├╥íCAUTODESKñ╜ÑqªP«╔ÑτñúÑX¿πª╣╡{ªí░⌡ªµ«╔ñ@⌐wñú╖|íuññ┬_ív⌐╬
- íuº╣Ñ■╡L╗~ív¬║½O├╥íC
-
-
- Description: Lexical analyser for the Geometry Calculator ADS application.
-
- *****************************************************************************/
-
-
- /****************************************************************************/
- /* INCLUDES */
- /****************************************************************************/
-
- #include "cal.h"
-
-
- /****************************************************************************/
- /* EXPORTED VARIABLES */
- /****************************************************************************/
-
- lex_output_type cal_lex; /* Output from the lexical analyser */
-
-
- /****************************************************************************/
- /* STATIC VARIABLES AND FUNCTIONS */
- /****************************************************************************/
-
- /* Keyword table */
-
- static struct {char *ident; symbol_type symbol;} kw[] =
- {
- "PI", pi_sym,
- "GETVAR", getvar_sym,
- "CVUNIT", cvunit_sym,
- };
-
- #define NKWS ELEMENTS(kw) /* Number of keywords */
-
- static char ch; /* The current character */
- static char *ch_ptr; /* Pointer to the next character */
- static int end_of_line; /* TRUE=next_char() reached EOLN */
-
- static void str_toupper _((char *str));
- static symbol_type is_keyword _((char *ident));
- static void next_char _((void));
- static void number _((void));
- static void number_angle_or_feet _((void));
-
-
- /****************************************************************************/
- /*.doc str_toupper(internal)*/
- /*+
- Converts the given string to upper case (I cannot understand why this is
- not a standard function somewhere in a standard library).
- -*/
- /****************************************************************************/
-
-
- static void
- /*FCN*/str_toupper(str)
-
- char *str;
- {
- while ((*str = ads_toupper(*str)) != 0) {
- str++;
- }
- } /*str_toupper*/
-
-
- /****************************************************************************/
- /*.doc is_keyword(internal)*/
- /*+
- Returns the keyword symbol if the given identitier is a keyword or
- symbol 'ident_sym' if it is not.
- -*/
- /****************************************************************************/
-
-
- static symbol_type
- /*FCN*/is_keyword(ident)
-
- char *ident;
- {
- register int i;
-
- for (i = 0; i < NKWS; i++)
- if (strcmp(ident, kw[i].ident) == 0) {
- return(kw[i].symbol);
- }
- return(ident_sym);
- } /*is_keyword*/
-
-
- /****************************************************************************/
- /*.doc next_char(internal)*/
- /*+
- Delivers the next character from the input stream. The character is
- stored in 'ch', the pointer to the next character is 'ch_ptr'.
- -*/
- /****************************************************************************/
-
-
- static void
- /*FCN*/next_char()
- {
- if (*ch_ptr != EOS) {
- ch = ads_toupper(*ch_ptr++);
- } else {
- ch = ' ';
- end_of_line = TRUE;
- }
- } /*next_char*/
-
-
- /****************************************************************************/
- /*.doc number(internal)*/
- /*+
- Parses the terminal symbol NUMBER.
- -*/
- /****************************************************************************/
-
-
- static void
- /*FCN*/number()
- {
- char *sym_begin;
- char num_str[MAX_SYMBOL_LENGTH+1];
- int sym_len;
- int success;
-
- if (cal_err)
- return;
-
- cal_lex.sym = int_sym;
- sym_begin = ch_ptr - 1;
-
- while (ads_isdigit(ch)) {
- next_char();
- }
-
- if (ch == '.') {
- cal_lex.sym = real_sym;
- next_char();
- while (ads_isdigit(ch)) {
- next_char();
- }
- }
- if (ch == 'E') {
- cal_lex.sym = real_sym;
- next_char();
- if ((ch == '+') || (ch == '-'))
- next_char();
- if (!(ads_isdigit(ch))) {
- error(1, NULL);
- return;
- }
- do {
- next_char();
- } while (ads_isdigit(ch));
- }
-
- sym_len = ch_ptr - sym_begin - 1;
- if (end_of_line) {
- sym_len++;
- }
- if (sym_len > MAX_SYMBOL_LENGTH) {
- sym_len = MAX_SYMBOL_LENGTH;
- }
-
- strncpy(num_str, sym_begin, sym_len);
- num_str[sym_len] = EOS;
-
- success = sscanf(num_str, "%lf", &cal_lex.real_num);
- if (success != 1) {
- error(1, num_str);
- return;
- }
- if ((errno == ERANGE) || (errno == EDOM) ||
- (cal_lex.real_num == HUGE_VAL)) {
-
- error(1, num_str);
- return;
- }
- if ((cal_lex.sym == int_sym) &&
- ((cal_lex.real_num > 32767) || (cal_lex.real_num < -32768))) {
- error(3, NULL);
- return;
- }
- } /*number*/
-
-
- /****************************************************************************/
- /*.doc number_angle_or_feet(internal)*/
- /*+
- Parses the terminal symbols NUMBER, ANGLE and FEET-INCHES.
- -*/
- /****************************************************************************/
-
-
- static void
- /*FCN*/number_angle_or_feet()
- {
- if (cal_err)
- return;
-
- number();
- if (cal_err)
- return;
-
- if (ch == 'G') { /*grads*/
- cal_lex.sym = real_sym;
- cal_lex.real_num = cal_lex.real_num * 0.9;
- next_char();
-
- } else if (ch == 'R') { /*radians*/
- cal_lex.sym = real_sym;
- cal_lex.real_num = cal_lex.real_num / DEGRAD;
- next_char();
-
- } else if (ch == 'D') { /*<deg>d<min>'<sec>"*/
- double deg, min, sec;
-
- deg = cal_lex.real_num;
- min = sec = 0.0;
-
- next_char();
- if (!ads_isdigit(ch)) {
- goto End_degminsec;
- }
- number();
-
- if (ch == '\'') {
- min = cal_lex.real_num;
- next_char();
- if (!ads_isdigit(ch)) {
- goto End_degminsec;
- }
- number();
- }
-
- if (ch == '"') {
- sec = cal_lex.real_num;
- next_char();
- } else {
- error(34, NULL);
- return;
- }
-
- End_degminsec:
- if (cal_err)
- return;
-
- cal_lex.sym = real_sym;
- cal_lex.real_num = deg + min / 60.0 + sec / 3600.0;
-
- } else if ((ch == '\'') || (ch == '"')) { /*<feet>'<inches>"*/
- double feet = 0, inches = 0;
-
- if (ch == '\'') {
- feet = cal_lex.real_num;
-
- next_char();
- if (ch == '-') {
- next_char();
- }
-
- if (ads_isdigit(ch)) {
- number();
- if (ch != '"') {
- error(22, NULL);
- return;
- }
- inches = cal_lex.real_num;
- next_char();
- }
- } else {
- inches = cal_lex.real_num;
- next_char();
- }
-
- if (cal_err)
- return;
-
- cal_lex.sym = real_sym;
- cal_lex.real_num = 12 * feet + inches;
- } /*if*/
-
- } /*number_angle_or_feet*/
-
-
- /****************************************************************************/
- /*.doc cal_next_symbol(internal)*/
- /*+
- Delivers the next symbol from the input stream. The returned symbol
- is stored in the global structure 'cal_lex'.
- -*/
- /****************************************************************************/
-
-
- void
- /*FCN*/cal_next_symbol()
- {
- char *sym_begin;
- int sym_len;
- register int i;
-
- if (cal_err)
- return;
-
- while ((ch == ' ') && !end_of_line) {
- next_char();
- }
-
- if (ch == ' ') {
- cal_lex.sym = no_sym;
-
- } else if (ads_isalpha(ch)) {
-
- cal_lex.sym = ident_sym;
- sym_begin = ch_ptr - 1;
-
- do {
- next_char();
- } while (ads_isalnum(ch) || (ch == '_'));
-
- sym_len = ch_ptr - sym_begin - 1;
- if (end_of_line) {
- sym_len++;
- }
- if (sym_len > MAX_SYMBOL_LENGTH) {
- sym_len = MAX_SYMBOL_LENGTH;
- }
-
- strncpy(cal_lex.id, sym_begin, sym_len);
- cal_lex.id[sym_len] = EOS;
- str_toupper(cal_lex.id);
-
- /* Is it a keyword ? */
-
- cal_lex.sym = is_keyword(cal_lex.id);
- if (cal_lex.sym != ident_sym)
- return;
-
- /* Is it a function name? */
-
- for (i = 0; i < cal_funcs_number; i++) {
- if (strcmp(cal_lex.id, cal_funcs_table[i].name) == 0) {
- cal_lex.sym = func_sym;
- cal_lex.func_ptr = cal_funcs_table[i].func;
- return;
- } /*if*/
- } /*for*/
-
- } else if (ch == '\'') {
- /* The name of AutoLISP symbol enclosed in apostrophes */
-
- cal_lex.sym = ident_sym;
- next_char();
-
- i = 0;
- while (!end_of_line && (i < MAX_SYMBOL_LENGTH) && (ch != '\'')) {
- cal_lex.id[i++] = ch;
- next_char();
- }
- cal_lex.id[i] = EOS;
-
- if (end_of_line) {
- error(9, NULL);
- return;
- } if (ch != '\'') {
- error(31, cal_lex.id);
- return;
- }
-
- next_char();
-
- } else if (ads_isdigit(ch) || (ch == '.')) {
- number_angle_or_feet();
-
- } else if (ch == '[') { cal_lex.sym = lbracket_sym; next_char(); }
- else if (ch == ']') { cal_lex.sym = rbracket_sym; next_char(); }
- else if (ch == ',') { cal_lex.sym = comma_sym; next_char(); }
- else if (ch == '-') { cal_lex.sym = minus_sym; next_char(); }
- else if (ch == '+') { cal_lex.sym = plus_sym; next_char(); }
- else if (ch == '*') { cal_lex.sym = asterisk_sym; next_char(); }
- else if (ch == '/') { cal_lex.sym = slash_sym; next_char(); }
- else if (ch == '(') { cal_lex.sym = lparent_sym; next_char(); }
- else if (ch == ')') { cal_lex.sym = rparent_sym; next_char(); }
- else if (ch == '^') { cal_lex.sym = caret_sym; next_char(); }
- else if (ch == '@') { cal_lex.sym = at_sym; next_char(); }
- else if (ch == '<') { cal_lex.sym = lessthan_sym; next_char(); }
- else if (ch == '&') { cal_lex.sym = ampersand_sym; next_char(); }
- else if (ch == '=') { cal_lex.sym = equal_sym; next_char(); }
- else {
- cal_lex.id[0] = ch;
- cal_lex.id[1] = EOS;
- error(2, cal_lex.id);
- return;
- }
-
- } /*cal_next_symbol*/
-
-
- /****************************************************************************/
- /*.doc cal_lex_start(external)*/
- /*+
- Initializes the lexical analyser with the input string 'line'. Reads the
- first symbol ahead.
- -*/
- /****************************************************************************/
-
-
- void
- /*FCN*/cal_lex_start(line)
-
- char *line;
- {
- cal_err = 0;
- errno = 0;
- ch = ' ';
- ch_ptr = line;
- end_of_line = FALSE;
- next_char();
- cal_next_symbol();
- } /*cal_lex_start*/
-