parser into example python parsing whitespace

into - ¿Cómo los analizadores Python manejan la sangría?



split list python (1)

Al analizar un lenguaje de forma libre como C, es fácil para el analizador determinar cuándo se relacionan varias expresiones entre sí simplemente mirando los símbolos emitidos por el analizador. Por ejemplo, en el código.

if (x == 5) { a = b; c = d; }

El analizador puede decir que a = b y c = d son parte de una sola expresión porque hay un conjunto explícito de llaves alrededor del bloque. Además, el analizador sabe que las dos declaraciones en el bloque están relacionadas porque hay un punto y coma entre ellas. Esto podría codificarse fácilmente como un CFG usando algo como esto:

STMT ::= IF_STMT | EXPR; | BLOCK_STMT | STMT STMT IF_STMT ::= if ( EXPR ) STMT BLOCK_STMT ::= { STMT }

Sin embargo, en Python y otros lenguajes sensibles al espacio en blanco, no es tan fácil de hacer porque la estructura de las declaraciones solo se puede inferir desde su posición absoluta, que no creo que pueda codificarse fácilmente en un CFG. Por ejemplo, el código anterior en Python se vería así:

if x == 5: a = b c = d

Por más que lo intente, no puedo ver una manera de escribir un CFG que acepte esto, porque no puedo averiguar cómo codificar "dos declaraciones al mismo nivel de anidación" en un CFG.

¿Cómo los analizadores de Python agrupan las declaraciones como lo hacen? ¿Se basan en un escáner que inserta automáticamente tokens adicionales que denotan el inicio y el final de las declaraciones? ¿Producen un AST aproximado para el programa, luego tienen un pase adicional que reúne declaraciones basadas en su sangría? ¿Hay un CFG inteligente para este problema que me estoy perdiendo? ¿O utilizan un analizador más potente que un analizador estándar LL (1) o LALR (1) que puede tomar en cuenta el nivel de espacio en blanco?


Las indentaciones se manejan con dos "pseudo tokens": INDENT y DEDENT. Hay algunos detalles here . Para obtener más información, debe buscar en la fuente del analizador y el tokeniser de python.