Программа-интерпретатор для учебного языка SPL, страница 9

    return 1;

  else

    return 0;

}

где

Код
Символ

9

горизонтальная табуляция (‘\t’)

10

пробел (‘ ’)

32

перевод строки ¿ (‘\n’)

После внесения вышеописанных изменений функция get() правильно обрабатывает кириллические символы. Остается лишь переписать в функции word() ключевые слова на русский язык:

static char *serv[] = {"чтение", "печать", "возврат", "если", "тогда", "пока", "делать", "цел", "конст", "квдр"};


Текст программы

Ниже приведен исходник программы, состоящий из двух файлов: lex.h и spl.prog.c.

lex.h

#include <stdio.h>

#include <stdlib.h>

#include <ctype.h>

#include <string.h>

enum {READL = 257, PRITL, RETRL, IFL, THENL, WHILEL, DOL,

      CONSTL, INTL, IDEN, NUMB, SQRL};   //ключевые слова

int lex;                 //лексема

int lval;                /*её значение: если идентиф., то адрес       этого идентиф., если число - то                     число*/

char TNM[400];           //таблица идентификаторов

char *ptn = TNM;         //указатель на первый свободный                элемент в таблице идентификаторов

int nst = 0;             //номер строки в исходном файле

static char nch = '\n';  //текущий символ

FILE *PF;                //указатель на файл с исходным текстом

void get( void ); //функция получения новой лексемы

void number( void ); //если очередная лексема - число

void word( void ); //если очередная лексема - идентификатор

char *add( char *nm ); //для занесения идентификаторов в        таблицу идентификаторов TNM

int _isalpha( int p ) {

  int t;

  t = 256+p;

  if ((t >= 128 && t <= 159) ||

      (t >= 160 && t <= 175) ||

      (t >= 224 && t <= 239) || isalpha( p ))

    return 1;

  else

    return 0;

}

int _isdigit( int p ) {

  if (p >= 48 && p <= 57)

    return 1;

  else

    return 0;

}

int _isspace( int p) {

  if (p == 9 || p == 10 || p == 32)

    return 1;

  else

    return 0;

}

void get() {

  if (nch != EOF) {

    while (_isspace( nch )) {

      if (nch == '\n')

                         nst++;

      nch = getc( PF );

    }

    if (_isdigit( nch ))

      number();

    else

      if (_isalpha( nch ))

        word();

      else

        if (nch == '+' || nch == '-' || nch == '*' ||

nch == '/' || nch == '%' || nch == '(' ||

            nch == ')' || nch == ',' || nch == ';' ||

            nch == '=' || nch == '{' || nch == '}' ||

            nch == '@' || _isspace( nch )) {

          lex = nch;

          nch = getc( PF );

        }

        else {

          printf( "Недопустимый символ в строке nst = %i!\n", nst );

          exit( 0 );

        }

  }

  else

    lex = EOF;

  return;

}

void number() {

  for (lval = 0; _isdigit( nch ); nch = getc( PF ))

    lval = 10*lval+nch-'0';

  lex = NUMB;

  return;

}

void word() {

  char tx[40];

  char *p;

  int i;

  static char *serv[] = {"чтение", "печать", "возврат", "если", "тогда", "пока", "делать", "цел", "конст", "квдр"};

  static int cdl[] = {READL, PRITL, RETRL, IFL, THENL, WHILEL,

                      DOL, INTL, CONSTL, SQRL};

  for (p = tx; (_isdigit( nch ) || _isalpha( nch )); nch = getc( PF ))

    *(p++) = nch;

  *p = '\0';

  for (i = 0; i < 11; i++) {

    if (!strcmp( tx, serv[i] )) {

      lex = cdl[i];

      return;

    }

  }

  lex = IDEN;

  lval = (int) add( tx );

  printf( "Лексема tx = %s, ее значение lval = %i\n", tx, lval );

  return;

}

char *add( char *nm ) {

  char *p;