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

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

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

Ответить
DropSoft
новенький
Сообщения: 33
Зарегистрирован: 31.03.2013 13:47:40

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

Сообщение DropSoft »

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

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

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]
Аватара пользователя
Дож
энтузиаст
Сообщения: 900
Зарегистрирован: 12.10.2008 16:14:47

Сообщение Дож »

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

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.
DropSoft
новенький
Сообщения: 33
Зарегистрирован: 31.03.2013 13:47:40

Сообщение DropSoft »

Дож, спасибо! Кое-что прояснилось.
Единственно надо, чтобы 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
Аватара пользователя
Дож
энтузиаст
Сообщения: 900
Зарегистрирован: 12.10.2008 16:14:47

Сообщение Дож »

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

Сообщение Снег Север »

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

В стандартной поставке есть fcl-stl с реализацией словарей.
Ответить