Как Вы пошли бы о реализации правила вне игры?

Итак, у меня есть проверка, и она кажется застрявшей во втором цикле while.

Итак, пошли по шагам. Вы устанавливаете m=0, пока m <= 36 остается в силе, входя в том и только в том случае, если m % 6 == 0 это правда, если это так, некоторый код, то увеличивайте m на 1.

Теперь мы находимся в x = (savings - down_payment), x выдаст некоторое высокое положительное или отрицательное число, скажем, 20 000 долларов.

Пока x != 0.01, что всегда будет верно, потому что x никогда не будет 0,01. Таким образом, ваш цикл while будет бесконечно зависать здесь

11
задан Cheery 4 November 2008 в 13:58
поделиться

2 ответа

Я записал токенизаторы и синтаксические анализаторы для нескольких небольших центральных добавлением отступа проблемно-ориентированных языков за несколько прошлых лет, и что у Вас есть там взгляды, довольно разумные мне, для того, что это стоит. Если я не ошибаюсь, Ваш метод весьма схож с тем, что Python делает, например, который кажется, что должен нести некоторый вес.

Преобразование ОТСТУПА НОВОЙ СТРОКИ НОВОЙ СТРОКИ только к ОТСТУПУ, прежде чем это поразит синтаксический анализатор определенно, походит на правильный способ сделать вещи - это - боль (IME) для всегда заглядывания вперед для этого в синтаксическом анализаторе! Я на самом деле сделал тот шаг как отдельный слой в том, что закончило тем, что было тремя процессами шага: первое объединило то, что Ваш лексический анализатор и layouter делают минус весь материал предвидения НОВОЙ СТРОКИ (который сделал его очень простым), второе (также очень простой), слой свернул последовательные НОВЫЕ СТРОКИ и преобразовал ОТСТУП НОВОЙ СТРОКИ в просто ОТСТУП (или, на самом деле, ОТСТУП НОВОЙ СТРОКИ ДВОЕТОЧИЯ для РАСПОЛОЖЕНИЯ С ОТСТУПОМ, так как в этом случае всем блокам с отступом всегда предшествовали двоеточия), затем синтаксический анализатор был третьей стадией вдобавок ко всему Но это также имеет большой смысл мне сделать вещи путем, Вы описали их, особенно если бы Вы хотите разделить лексический анализатор от layouter, который, по-видимому, Вы хотели бы сделать при использовании инструмента генерации кода для создания лексического анализатора, например, как обычная практика.

У меня действительно было одно приложение, которое должно было быть немного более гибко о правилах добавления отступа, по существу оставив синтаксический анализатор для осуществления их при необходимости - следующее должно было быть допустимым в определенных контекстах, например:

this line introduces an indented block of literal text:
    this line of the block is indented four spaces
  but this line is only indented two spaces

который не работает ужасно хорошо с маркерами INDENT/DEDENT, так как Вы заканчиваете тем, что должны были генерировать один ОТСТУП для каждого столбца добавления отступа и равного количества DEDENTs на пути назад, если Вы не смотрите путь вперед для выяснения, куда уровни отступа собираются закончить тем, что были, который не кажется, что Вы хотели бы, чтобы токенизатор сделал. В этом случае я попробовал несколько разных вещей и закончил тем просто, что хранил счетчик в каждом маркере НОВОЙ СТРОКИ, который дал изменение в добавлении отступа (положительный или отрицательный) для следующей логической строки. (Каждый маркер также сохранил весь запаздывающий пробел, в случае, если ему было нужно сохранение; для НОВОЙ СТРОКИ сохраненный пробел включал сам EOL, любые прошедшие пустые строки и добавление отступа на следующей логической строке.) Никакой отдельный ОТСТУП или маркеры DEDENT вообще. Получение синтаксического анализатора иметь дело с этим было немного большим количеством работы, чем просто вложенные ОТСТУПЫ и DEDENTs, и, возможно, хорошо было адом со сложной грамматикой, которой был нужен необычный парсер-генератор, но это не было почти настолько плохо, как я боялся, также. Снова, никакая потребность в синтаксическом анализаторе для смотрения вперед от НОВОЙ СТРОКИ, чтобы видеть, существует ли ОТСТУП, подходящий в этой схеме.

Однако, я думаю, что Вы согласились бы, что разрешение и сохранение всего способа выглядящего сумасшедшим образом пробела в tokenizer/layouter и разрешение синтаксическому анализатору решить, что является литералом и что является кодом, являются определенным необычным требованием! Вы, конечно, не хотели бы, чтобы Ваш синтаксический анализатор был обременен тем счетчиком добавления отступа, если бы Вы просто хотели смочь проанализировать код Python, например. Путем Вы делаете, вещи почти наверняка правильный подход для Вашего приложения и многих других, кроме того. Хотя, если у кого-либо еще есть мысли о том, как лучше всего сделать этот вид вещи, я, очевидно, любил бы слышать их....

8
ответ дан 3 December 2019 в 09:21
поделиться

Недавно я экспериментировал с этим и пришел к выводу, что, по крайней мере, для моих нужд, я хотел, чтобы НОВЫЕ СТРОКИ отмечали конец каждого «утверждения», независимо от того, было ли оно последним в блоке с отступом или нет, то есть мне нужны символы новой строки даже до DEDENT.

Мое решение состояло в том, чтобы перевернуть его с ног на голову, и вместо NEWLINES, обозначающих конец строк, я использую токен LINE, чтобы отметить начало строка.

У меня есть лексер, который сворачивает пустые строки (включая строки, содержащие только комментарии) и выдает один токен LINE с информацией об отступе последней строки. Затем моя функция предварительной обработки берет этот поток токенов и добавляет «между» строками, где отступы изменяются, или ОТВЕДЕНИЕ. Таким образом,

line1
    line2
    line3
line4

предоставит поток токенов

LINE "line1" INDENT LINE "line2" LINE "line3" DEDENT LINE "line4" EOF

. Это позволяет мне писать четкие грамматические конструкции для операторов, не беспокоясь об обнаружении конца операторов, даже если они заканчиваются вложенными субблоками с отступом, что может быть сложно, если вы сопоставляете NEWLINES (и DEDENTS) вместо этого.

Вот ядро ​​препроцессора, написанное на O'Caml:

  match next_token () with
      LINE indentation ->
        if indentation > !current_indentation then
          (
            Stack.push !current_indentation indentation_stack;
            current_indentation := indentation;
            INDENT
          )
        else if indentation < !current_indentation then
          (
            let prev = Stack.pop indentation_stack in
              if indentation > prev then
                (
                  current_indentation := indentation;
                  BAD_DEDENT
                )
              else
                (
                  current_indentation := prev;
                  DEDENT
                )
          )
        else (* indentation = !current_indentation *)
          let  token = remove_next_token () in
            if next_token () = EOF then
              remove_next_token ()
            else
              token
    | _ ->
        remove_next_token ()

Я еще не добавил поддержку круглых скобок, но это должно быть простое расширение. Однако он позволяет избежать появления случайной СТРОКИ в конце файла.

но это должно быть простое расширение. Однако он позволяет избежать появления случайной СТРОКИ в конце файла.

но это должно быть простое расширение. Однако он позволяет избежать появления случайной СТРОКИ в конце файла.

3
ответ дан 3 December 2019 в 09:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: