Napisałem już generator, który rozwiązuje problem, ale chciałbym poznać najlepszy możliwy sposób implementacji reguły off-side.Jak byś poszła na temat wdrażania zasad zewnętrznych?
Krótko: Off-side rule oznacza w tym kontekście, że wcięcie zostaje rozpoznane jako element syntaktyczny.
Oto przepis na spalonym Pseudokod dokonywania tokenizers przechwytującej wcięcie w postaci użytkowej, nie chcę, aby ograniczyć odpowiedzi poprzez język:
token NEWLINE
matches r"\n\ *"
increase line count
pick up and store the indentation level
remember to also record the current level of parenthesis
procedure layout tokens
level = stack of indentation levels
push 0 to level
last_newline = none
per each token
if it is NEWLINE put it to last_newline and get next token
if last_newline contains something
extract new_level and parenthesis_count from last_newline
- if newline was inside parentheses, do nothing
- if new_level > level.top
push new_level to level
emit last_newline as INDENT token and clear last_newline
- if new_level == level.top
emit last_newline and clear last_newline
- otherwise
while new_level < level.top
pop from level
if new_level > level.top
freak out, indentation is broken.
emit last_newline as DEDENT token
clear last_newline
emit token
while level.top != 0
emit token as DEDENT token
pop from level
comments are ignored before they are getting into the layouter
layouter lies between a lexer and a parser
Ten Layouter nie generuje więcej niż jeden na NEWLINE czas i nie generuje NEWLINE, gdy pojawi się wcięcie. Dlatego też reguły analizy składniowej są dość proste. Myślę, że jest całkiem niezły, ale poinformuj, czy jest lepszy sposób na osiągnięcie tego.
Podczas korzystania z tego przez chwilę zauważyłem, że po DEDENTACH może i tak być fajnie emitować newline, w ten sposób można oddzielić wyrażenia za pomocą NEWLINE, jednocześnie zachowując INDENT DEDENT jako zwiastun dla wyrażenia.
Twój kod nie jest w stanie emitować wielu DEDENT-ów, ani nie uwzględnia dedycji przed EOF. Może być przydatna dla czegoś, ale te rzeczy są ważniejsze niż wsparcie dla nawiasów. – Cheery
Nie przejmuj się również specjalną obsługą nawiasów, po prostu przegapisz najlepszy punkt, tak jak robi to python. Celem układania jest zapewnienie doskonałej składni wieloliniowej, nie koliduje z nawiasami, chyba że nie jesteś w stanie połączyć tych dwóch. – Cheery
Mój kod emituje wiele DEDENT, więc myślę, że źle to odczytałeś. Ale zgadzam się, że chciałbym czegoś bardziej przypominającego Haskella niż Pythona, więc potrzebuję nowego podejścia. – dkagedal