トリックを実行するジェネレーターを既に作成しましたが、オフサイドルールを実装するための最良の方法を知りたいです。
手短に:オフサイド ルールとは、このコンテキストでは、インデントが構文要素として認識されることを意味します。
これは、使用可能な形式でインデントをキャプチャするトークナイザーを作成するための疑似コードのオフサイド ルールです。言語によって回答を制限したくありません。
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
このレイアウタは、一度に複数の NEWLINE を生成することはなく、インデントが発生しても NEWLINE を生成しません。したがって、解析ルールは非常に単純なままです。かなり良いと思いますが、それを達成するためのより良い方法があればお知らせください。
しばらくこれを使用しているうちに、DEDENT の後にとにかく改行を発行するのが良いことに気付きました。この方法では、INDENT DEDENT を式のトレーラーとして保持しながら、NEWLINE で式を区切ることができます。