как перевести на Паскаль?

Форум для изучающих FPC и их учителей.

Модератор: Модераторы

как перевести на Паскаль?

Сообщение DropSoft » 19.04.2019 16:21:23

Подскажите, как красиво и правильно нижеследующий фрагмент перевести с питона на паскаль?

Код: Выделить всё
class Lexer:

   NUM, ID, IF, ELSE, WHILE, DO, LBRA, RBRA, LPAR, RPAR, PLUS, MINUS, LESS, \
   EQUAL, SEMICOLON, EOF = range(16)

   WORDS = { 'if': IF, 'else': ELSE, 'do': DO, 'while': WHILE }

   ch = ' ' # допустим, первый символ - это пробел

   def next_tok(self):
      self.value = None
      self.sym = None
      while self.sym == None:
         if self.ch.isalpha():
            ident = ''
            while self.ch.isalpha():
               ident = ident + self.ch.lower()
               self.getc() # читаем очередной символ в ch
            if ident in Lexer.WORDS:
               self.sym = Lexer.WORDS[ident]
DropSoft
новенький
 
Сообщения: 31
Зарегистрирован: 31.03.2013 13:47:40

Re: как перевести на Паскаль?

Сообщение Дож » 19.04.2019 17:42:20

Код: Выделить всё
uses
  SysUtils,
  strutils;

type
TLexer = object
public type
  TToken = (NUM, ID, _IF, _ELSE, _WHILE, _DO, LBRA, RBRA, LPAR, RPAR, PLUS,
            MINUS, LESS, EQUAL, SEMICOLON, EOF);
public const
  WORDS: array[0 .. 4 - 1] of AnsiString = ('if', 'else', 'do', 'while');
private
  FCh: AnsiChar;
  FValue: Pointer;
  FSym: AnsiString;
protected
  procedure GetC; virtual;
public
  constructor Init;
  procedure NextTok;
end;

procedure TLexer.GetC;
begin
  Read(FCh);
end;

constructor TLexer.Init;
begin
  FCh := 'i';
end;

function IsAlpha(C: AnsiChar): Boolean;
begin
  IsAlpha := C in ['a'..'z', 'A'..'Z'];
end;

procedure TLexer.NextTok;
var
  Ident: AnsiString;
begin
  FValue := nil;
  FSym := '';
  while FSym = '' do begin
    if IsAlpha(FCh) then begin
      Ident := '';
      while IsAlpha(FCh) do begin
        Ident := Ident + LowerCase(FCh);
        GetC;
      end;
      if AnsiIndexStr(Ident, WORDS) <> -1 then
        FSym := Ident;
    end;
  end;
end;

begin
end.
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 899
Зарегистрирован: 12.10.2008 16:14:47

Re: как перевести на Паскаль?

Сообщение DropSoft » 19.04.2019 18:42:30

Дож, спасибо! Кое-что прояснилось.
Единственно надо, чтобы FSym был элементом множества TToken, а не строкой.

Потому что я не указал, но есть еще такое определение:
SYMBOLS = { '{': LBRA, '}': RBRA, '=': EQUAL, ';': SEMICOLON, '(': LPAR, ')': RPAR, '+': PLUS, '-': MINUS, '<': LESS }

И еще, как можно найти индекс элемента FSym в TToken?
А то сейчас у меня так, но это громоздко.
Код: Выделить всё
    else if Fch in ['{', '}', '=', ';', '(', ')', '+', '-', '<'] then
    begin
      case Fch of                  // если символ
        '{': Fsym := LBRA;
        '}': Fsym := RBRA;
        '=': Fsym := EQUAL;
        ';': Fsym := SEMICOLON;
        '(': Fsym := LPAR;
        ')': Fsym := RPAR;
        '+': Fsym := PLUS;
        '-': Fsym := MINUS;
        '<': Fsym := LESS;
      end;
      Getc();
    end
DropSoft
новенький
 
Сообщения: 31
Зарегистрирован: 31.03.2013 13:47:40

Re: как перевести на Паскаль?

Сообщение Дож » 19.04.2019 23:59:01

AnsiIndexStr возвращает номер в списке. Можно объявить и заполнить array[AnsiChar] of TToken. А самый близкий аналог -- воспользоваться любой мапой/словарём (стандартного встроенного в язык нет, нужно смотреть либы).
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 899
Зарегистрирован: 12.10.2008 16:14:47

Re: как перевести на Паскаль?

Сообщение Снег Север » 20.04.2019 08:11:53

Дож писал(а):воспользоваться любой мапой/словарём (стандартного встроенного в язык нет, нужно смотреть либы).

В стандартной поставке есть fcl-stl с реализацией словарей.
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 3038
Зарегистрирован: 27.11.2007 16:14:47


Вернуться в Обучение Free Pascal

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2

Рейтинг@Mail.ru