Пигменты новой строки и пробелы вызывают лексические ошибкиPython

Программы на Python
Anonymous
Пигменты новой строки и пробелы вызывают лексические ошибки

Сообщение Anonymous »

(Этот вопрос необходимо переработать, поскольку все проблемы, кроме тех, которые связаны с условными инструкциями, уже решены. В нынешнем виде вопрос — это беспорядок)
Во-первых, большое примечание. : Я не программист на Python. Я просто знаю достаточно, прочитав документацию Pygments и просматривая источники доступных лексеров Pygments на Github, чтобы знать, как написать лексер Pygments.
Я работал над подсветкой синтаксиса сборки Jazz / SASM Saturn в Pygments. Когда я впервые начал это начинание, я думал, что задача будет чрезвычайно простой, но вскоре я столкнулся с проблемами, связанными с особенностями обработки Pygments новой строки и пробелов, в деталях которых я не разбираюсь и дергаю себя за волосы. безуспешно пытаюсь заставить лексер работать, поэтому мой пост здесь.
Синтаксис Jazz/SASM имеет некоторые требования, чувствительные к пробелам, в частности, метка должна начинаться в первом столбце или два — я не знаю, является ли это частью проблемы.
Первая проблема заключается в том, что когда метка начинается во втором столбце и ей предшествует пустая строка (т. просто '\n' ) метка помечается как ошибка лексики или вся строка помечается как ошибка лексики, если комментарий следует за меткой в ​​той же строке. РЕДАКТИРОВАТЬ Кажется, что что-то (т. е. любой допустимый ассемблерный код Jazz/SASM, комментарии и т. д.) должно предшествовать пустой строке, чтобы воспроизвести эту проблему.
ВВОД:

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

* Replace this with any valid Jazz / SASM comments or code

=lbl1 * This is a comment
ВЫВОД:
[img]https://i.sstatic.net /530twm0H.png[/img]

Вторая проблема довольно странная, и я понятия не имею, что ее вызывает: если комментарий на всю строку (который должен начинаться со звездочки в первом столбце) предшествует пустая строка, то если в тексте есть инструкция, которая, как можно подумать, будет закомментирована, вместо этого генерируется лексическая ошибка для указанного текста инструкции. EDIT Кажется, я не могу точно воспроизвести эту проблему (возможно, что-то не так с лексическим кортежем для класса инструкций, который я использовал, или инструкция была неправильно сформирована?), но я заметил, что то, что должно быть комментарием, обрабатывается как инструкция. Кроме того, как и в случае с первой проблемой, перед пустой строкой должно быть что-то, чтобы возникла проблема.
ВВОД:

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

* Replace this with any valid Jazz / SASM comments or code

* B=0 S
ВЫВОД:
[img]https://i.sstatic.net /26XdiFyM.png[/img]

Для решения третьей проблемы необходимо дальнейшее объяснение синтаксиса Jazz/SASM: за всеми условными инструкциями должна следовать метка GOYES или просто RTNYES. на следующей строке. Первая проблема, с которой я здесь сталкиваюсь, заключается в том, что если условная инструкция имеет конечные пробелы, которые должны обрабатываться кодом обработки комментариев, тогда Pygments помечает указанные пробелы как ошибку лексирования.< /p>
ВВОД:

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

* Replace this with any valid Jazz / SASM comments or code

?A=B W
GOYES lbl1
ВЫВОД:
[img]https://i.sstatic.net /TO9hz5Jj.png[/img]

Кроме того, условные инструкции, по-видимому, невосприимчивы к чему-либо, вызывающему ошибки лексики, связанные с первой проблемой, т.е. если условной инструкции предшествует метка в той же строке, независимо от того, начинается ли она в первом или втором столбце, и ей предшествует пустая строка, то Pygments, похоже, обрабатывает всю строку без лексических ошибок.
ВВОД:

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

* Replace this with any valid Jazz / SASM comments or code

?A=B W
GOYES lbl1

ВЫВОД:
[img]https://i.sstatic.net /UmDpS8QE.png[/img]

Наконец, обязательная метка GOYES или RTNYES на следующей строке после условия всегда помечается как лексическая. ошибка Pygments.
ВВОД:

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

* Replace this with any valid Jazz / SASM comments or code

?D=C W
GOYES lbl1

?B=A P
RTNYES
ВЫВОД:
[img]https://i.sstatic.net /jtrcnP8F.png[/img]

Я знаю, что все вышеперечисленное может не иметь особого смысла, поскольку оно отделено от исходного кода, поэтому, WLOG, я включил Код лексера Pygments, который просто обрабатывает два класса инструкций: пробелы, метки и комментарии. Классы инструкций: установка регистра в ноль и условные инструкции, выполняющие сравнение двух регистров на равенство.
( Обратите внимание, что следующий фрагмент исходного кода был обновлен, поэтому проблемы, описанные выше, за исключением проблем, связанных с условными инструкциями, были устранены)

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

from pygments.lexer import RegexLexer, bygroups
from pygments.token import *
import logging

class SasmJazzLexer(RegexLexer):
name = 'SASM'
aliases = ['SASM', 'Sasm', 'sasm', 'JAZZ', 'Jazz', 'jazz']
filenames = ['*.A', '*.a']

# Register fields
fields = r'(P|WP|XS|X|S|M|B|A|W)'

# Regex for label or symbol
symbol = r'((?:[:=][(=:#0-9][^,\s)]{,11})|(?:[:=]?[^(=:#0-9*,\s)\n][^,\s]{,11}))'

tokens = {
'root': [
# Whitespace
(r'^\s+$', Whitespace),

# Single line comment starting with '*' in column one
(r'^\*.*$', Comment.Single),

# Whitespace or instructions
(r'^( {2,})|(\t)\s*', Whitespace, 'possible_instructions'),

# Label starting on column one or two and followed by a comment
(r'(^ ?)' + symbol + r'(\s+)(\*.*$)', bygroups(Whitespace, Name.Label, Whitespace, Comment.Single)),

# Label starting in column one or two and followed by whitespace or instructions
(r'(^ ?)' + symbol + r'(\s+)', bygroups(Whitespace, Name.Label, Whitespace), 'possible_instructions'),
],
'possible_instructions': [
# Just whitespace or empty line -- emit token and bail
(r'\s+$', Whitespace, '#pop'),

#
# Register tests
#

(r'(\?)([A-C])(=)([A-C])(\s+)' + fields, bygroups(Punctuation, Name.Builtin, Operator, Name.Builtin, Whitespace, Name.Builtin), ('possible_comment_cond', 'conditionals')),
(r'(\?)([CD])(=)([CD])(\s+)' + fields, bygroups(Punctuation, Name.Builtin, Operator, Name.Builtin, Whitespace, Name.Builtin), ('possible_comment_cond', 'conditionals')),
(r'(\?)(([A-D])(=)(\3))(\s+)' + fields, bygroups(Punctuation, Error, Name.Builtin, Operator, Name.Builtin, Whitespace, Name.Builtin), ('possible_comment_cond', 'conditionals')),

#
# Arithmetic instructions
#

# r=0 fs
# possibly followed by a comment
(r'([A-D])(=)(0)(\s+)' + fields, bygroups(Name.Builtin, Operator, Name.Builtin, Whitespace, Name.Builtin), 'possible_comment'),
],
'possible_comment': [
#
# Comment processing code
#

# Just whitespace or empty line -- emit token and bail
(r'\s*$', Whitespace, '#pop:2'),

# Trailing comment
(r'\s+\S.*$', Comment.Single, '#pop:2')
],
'possible_comment_cond': [
#
# Comment processing code for conditionals
#

# Just whitespace or empty line -- emit token and bail
(r'\s*$', Whitespace, '#pop'),

# Trailing comment
(r'\s+\S.*$', Comment.Single, '#pop')
],
'conditionals':  [
#
# GOYES and RTNYES processing code
#

(r'(^ {2,}\s*)(GOYES)(\s+)' + symbol, bygroups(Whitespace, Keyword, Whitespace, Name.Label), 'possible_comment'),
(r'(^ {2,}\s*)(RTNYES)', bygroups(Whitespace, Keyword), 'possible_comment'),
]
}
В приведенном выше примере, если строка не является полнострочным комментарием, она либо соответствует метке в первом или втором столбце, за которой, возможно, следует инструкция (в состоянии «possible_instructions» ), после которого может следовать комментарий (обрабатываемый состоянием «possible_comment», который в этом случае не требует использования звездочки), разделенный инструкцией пробелами.
Для условные инструкции, в стек помещаются два состояния:

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

('possible_comment_cond', 'conditionals')
Состояние «possible_comment_cond» необходимо, потому что каждый кортеж в состоянии «possible_comment» извлекает два уровня стека, которые выталкивают состояние «условия», необходимое для обработки «метки GOYES» или 'RTNYES', который должен следовать условной инструкции.
Обратите внимание, что я создал полный HTML-документ для проверки моего лексера, используя

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

python3 -m pygments -f html -O full -o test.html -x -l pygments_sasm_lexer_5.py:SasmJazzLexer test.txt
Надеюсь, я включил достаточно информации для понимания этого вопроса. Если нет, прокомментируйте, и я добавлю дополнительную информацию, если необходимо.
Кроме того, я прошу прощения за уродливые скриншоты отображаемого выходного HTML-кода, но я не могу вставить все пять выходных HTML-кодов, не превысив ограничение на число символов Stackoverflow. >

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

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

symbol = r'((?:[:=][(=:#0-9][^, )]{,11})|(?:[:=]?[^(=:#0-9*, ][^, )]{,11}))'
Чтобы разбить приведенное выше регулярное выражение, оно должно соответствовать чему-либо длиной до двенадцати символов, кроме запятой, пробела или правых круглых скобок, и оно начинается со «специального символа» ( '( ', '=', ':', '#' и от '0' до '9') тогда и только тогда, когда перед символом стоит префикс '=' или ':' . символ не начинается со специального символа, а также не начинается со звездочки, затем он соответствует чему угодно (опять же, кроме запятой, пробела или правой скобки), опять же, длиной до двенадцати символов и необязательно с префиксом ':' или '=' .
Насколько я вижу, предоставленное мной регулярное выражение работает так, как я объяснил выше.
Кроме того, в обработке пробелов была небольшая ошибка: указанный пробел передавался в группах захвата регулярных выражений в обратный вызов «bygroups» — теперь он обрабатывается отдельно и получает тип токена «Пробелы». однако не производит никаких изменений в выводе.
Я не понимаю, что вызывает лексические ошибки, перечисленные в этом вопросе.
Я зарегистрировал/установил свой собственный лексер с Pygments на общесистемном уровне и запустил на нем отладчик лексера с тестовым вводом, и он выглядит, как проблема вызвана переводами строк.
В частности, я думаю, что нашел проблему или, по крайней мере, часть проблемы: регулярные выражения в моем коде неправильно обрабатывают символы новой строки. , точнее, вообще ими не занимаюсь - совсем вылетело из головы - упс.
Когда у меня будет время, если я смогу решить проблемы вызвано этим, тогда я отвечу на свой вопрос.

Ну, я ошибочно подумал, судя по выводам отладчика lexer, что часть проблемы заключалась в вызвано пустыми строками, состоящими только из новой строки, но, похоже, Pygments по умолчанию просто поглощает пустые строки.
Проблемы, которые я представил здесь, за исключением проблем с условными инструкциями, появляются Это было вызвано отсутствием кортежа, который обрабатывает строки, состоящие полностью из пробелов, а также глупой ошибкой в ​​регулярном выражении символа. Что касается регулярного выражения, я случайно дополнил класс символов в квадратных скобках, который включал пробел, хотя мне действительно нужен был класс экранированных символов '\s' вместо пробела.
Правильное регулярное выражение следует:< /p>

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

r'((?:[:=][(=:#0-9][^,\s)]{,11})|(?:[:=]?[^(=:#0-9*,\s)\n][^,\s]{,11}))'
(Это также было исправлено в исходном фрагменте, а также удалено множество лишних символов EOL '$ из регулярных выражений, обрабатывающих пробелы)
Что касается проблем с условными инструкциями, я думал, что добавление '\s*' в начальную часть регулярного выражения с пробелами может решить проблему, но, к сожалению, "метка GOYES" или "RTNYES" по-прежнему помечено как лексическая ошибка (а также любые комментарии в той же строке и после тестовой инструкции). Почему, понятия не имею.

Подробнее здесь: https://stackoverflow.com/questions/785 ... ing-errors

Вернуться в «Python»