Pythonが英語よりも簡単な場合があるため、ここではこの説明をPythonに変換します。このような作品の現実世界のパーサ(自分で書いたもの)を見ることができます。hereここで
import re
code = """
for i in range(10):
if i % 2 == 0:
print(i)
print("Next number")
print("That's all")
for i in range(10):
if i % 2 == 0:
print(i)
print("That's all again)
for i in range(10):
if i % 2 == 0:
print(i)
print("That's all")
"""
def get_indent(s) -> int:
m = re.match(r' *', s)
return len(m.group(0))
def add_token(token):
print(token)
INDENT="indent"
DEDENT="dedent"
indent_stack = [0]
# Before the first line of the file is read, a single zero is pushed on the stack
for line in code.splitlines():
print("processing line:", line)
indent = get_indent(line)
# At the beginning of each logical line, the line’s
# indentation level is compared to the top of the stack.
if indent > indent_stack[-1]:
# If it is larger, it is pushed on the stack,
# and one INDENT token is generated.
add_token(INDENT)
indent_stack.append(indent)
elif indent < indent_stack[-1]:
while indent < indent_stack[-1]:
# If it is smaller, ...
# all numbers on the stack that are larger are popped off,
# and for each number popped off a DEDENT token is generated.
add_token(DEDENT)
indent_stack.pop()
if indent != indent_stack[-1]:
# it must be one of the numbers occurring on the stack;
raise IndentationError
while indent_stack[-1]>0:
# At the end of the file, a DEDENT token is generated for each number
# remaining on the stack that is larger than zero.
add_token(DEDENT)
indent_stack.pop()
が出力されます。
processing line:
processing line: for i in range(10):
processing line: if i % 2 == 0:
indent
processing line: print(i)
indent
processing line: print("Next number")
dedent
processing line: print("That's all")
dedent
processing line:
processing line: for i in range(10):
processing line: if i % 2 == 0:
indent
processing line: print(i)
indent
processing line: print("That's all again)
dedent
dedent
processing line:
processing line: for i in range(10):
processing line: if i % 2 == 0:
indent
processing line: print(i)
indent
processing line: print("That's all")
dedent
dedent
File "<string>", line unknown
IndentationError