Управление добавлением отступа при разработке маленького Python как язык

Я разрабатываю маленький Python как язык с помощью гибкого провода, byacc (для лексического и анализируя) и C++, но у меня есть несколько вопросов относительно управления объемом.

так же, как Python это использует пробелы (или вкладки) для добавления отступа, не только этого, но и я хочу реализовать индекс, повреждающийся как, например, если бы Вы вводите "повреждение 2" внутри некоторое время цикл, это в другом цикле с условием продолжения, который это не только повредило бы от последнего, но от первого цикла также (следовательно номер 2 после повреждения) и так далее.

пример:

while 1
    while 1
        break 2
        'hello world'!! #will never reach this. "!!" outputs with a newline
    end
    'hello world again'!! #also will never reach this. again "!!" used for cout
end
#after break 2 it would jump right here

но так как у меня нет "анти-" символа табуляции для проверки, когда объем заканчивается (как C, например, я просто использовал бы '}' символ), я задавался вопросом, будет ли этот метод лучшее:

Я определил бы глобальную переменную, как "интервал tabIndex" на моем yacc файле, к которому я получу доступ в своем файле закона с помощью экстерна. затем каждый раз, когда я нахожу символ табуляции на своем файле закона, я увеличил бы ту переменную 1. при парсинге на моем yacc файле, если бы я нахожу ключевое слово "повреждения", я постепенно уменьшился бы суммой, введенной после него от tabIndex переменной, и когда я достигаю и EOF после компиляции, и я получаю tabIndex! = 0 я произвел бы ошибку компиляции.

теперь проблема, что состоит в том, чтобы видеть лучший способ, было ли добавление отступа уменьшено, я должен считать \b (клавиша Backspace) символы от закона и затем уменьшить tabIndex переменную (когда пользователь разве использует, не повреждается)?

другой метод для достижения этого?

также просто другой небольшой вопрос, я хочу, чтобы каждый исполняемый файл имел свою начальную точку на вызванной функции, запускаются (), должен я hardcode это на мой yacc файл?

жаль о долгом вопросе любая справка значительно ценится. также, если бы кто-то может обеспечить, yacc файл для Python был бы хорош как инструкция (пытался считать Google и не имел никакой удачи).

заранее спасибо.

5
задан Jim Ferrans 30 April 2010 в 05:24
поделиться

2 ответа

В настоящее время я реализую язык программирования, довольно похожий на этот (включая многоуровневое разбиение, как ни странно). Моим решением было заставить токенизатор выдавать лексемы с отступом и вычитанием на основе отступа. Например:

while 1: # colons help :)
    print('foo')
    break 1

становится:

["while", "1", ":",
    indent,
    "print", "(", "'foo'", ")",
    "break", "1",
    dedent]

Это несколько усложняет работу токенизатора с '\n'. Кроме того, я написал токенизатор и парсер с нуля, так что я не уверен, что это осуществимо в lex и yacc.

Edit:

Semi-working pseudocode example:

level = 0
levels = []
for c = getc():
    if c=='\n':
        emit('\n')
        n = 0
        while (c=getc())==' ':
            n += 1
        if n > level:
            emit(indent)
            push(levels,n)
        while n < level:
            emit(dedent)
            level = pop(levels)
            if level < n:
                error tokenize
        # fall through
    emit(c) #lazy example
8
ответ дан 13 December 2019 в 19:23
поделиться

Очень интересное упражнение. Разве вы не можете использовать ключевое слово end , чтобы проверить, когда заканчивается область действия?

С другой стороны, я никогда не встречал языка, который позволял бы вырваться из нескольких вложенных циклов одновременно. Для этого может быть веская причина ...

3
ответ дан 13 December 2019 в 19:23
поделиться