Aclaración sobre gramáticas, lexers y analizadores


8

Información de antecedentes ( puede omitirse ): estoy trabajando en una tarea que nos asignaron en la que tenemos que diseñar una gramática para un DSL que se nos ha proporcionado. La gramática debe estar en BNF o EBNF. Además de otra cosa, estamos siendo evaluados sobre las reglas léxicas en la gramática y las reglas de análisis, por ejemplo, si las reglas son adecuadas para el subconjunto de idioma, qué tan exhaustivas son estas reglas, qué tan claras son las reglas, etc.

Lo que no entiendo es si estas reglas están cubiertas en una gramática definida en BNF (es un tema nuevo para nosotros).

La pregunta : ¿una gramática para un idioma determinado que se ha definido en BNF o EBNF contiene / proporciona reglas para el análisis léxico y / o análisis ? (¿ o tienen que especificarse en otro lugar? )

Además, ¿qué se consideraría una regla léxica? ¿Y qué se consideraría una regla de análisis?


1
BNF es solo una sintaxis que describe completamente la gramática, al igual que regex describe completamente un lenguaje normal
ratchet freak

44
Sí, puede definir tanto lexing como parsing en una única descripción similar a BNF; consulte PEG, por ejemplo. La distinción entre lexing y parsing es bastante arbitraria y obsoleta.
SK-logic

Respuestas:


8

Sí, una gramática BNF contiene todas las reglas que necesita para el análisis y análisis léxico. La diferencia entre los dos es un poco confusa. Un buen ejemplo de una regla léxica en EBNF sería:

number = [ "-" ], digit, { digit } ;
digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ;

Por lo general, los lexers se pueden implementar utilizando un código relativamente simple. Puede buscar una cadena para el siguiente espacio, luego ver si su resultado comienza con un "-" opcional, contiene al menos un dígito después de eso y solo contiene dígitos después de eso. Los Lexers solían ser casi siempre un paso separado, pero hoy en día generalmente se agrupan junto con el analizador. De ahí la confusión.

Una regla del analizador usaría el numberno terminal para hacer algo más grande, como la siguiente expresión de suma.

add = number, "+", number

Aunque están mezclados en el mismo archivo, su profesor aún querrá ver una distinción clara entre las reglas "lexer" y las reglas "parser". Por ejemplo, no hagas esto:

add = {"0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" }, "+",
      {"0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" }

Ese error no solo es propenso, es difícil de leer y de implementar.


¡Gracias, la sección sobre cómo hacer una distinción clara entre las reglas "lexer" y las reglas "parser" realmente me ayudó a comprender para qué estamos siendo evaluados!
The_Neo

4

La gramática para el análisis léxico generalmente se especifica mediante expresiones regulares (especialmente para proyectos de tipo universitario). Acepta un lenguaje regular.

Un analizador generalmente acepta un lenguaje sin contexto, que puede especificarse a través de BNF.

La distinción entre un analizador y un escáner (o analizador léxico) es algo artificial, pero facilita la escritura de analizadores.

Ver http://en.wikipedia.org/wiki/Chomsky_hierarchy


Sacas un buen punto sobre los proyectos universitarios que a menudo son diferentes. Le corresponde aclarar los requisitos exactos con su profesor.
Karl Bielefeldt

2

La respuesta a su pregunta es ciertamente Sí, las reglas de análisis y lexing pueden y se especifican utilizando un EBNF (que en realidad es solo una forma más compacta de un BNF). Sin embargo, en los compiladores de calidad de producción, la siguiente parte de la respuesta es diferente.

La mayoría de los idiomas tienen una gramática que no tiene contexto y se ajusta a un conjunto de reglas relacionadas con la búsqueda anticipada y el retroceso. Las gramáticas más comunes son LL (1) y LR (1). Las gramáticas LL (1) permiten una gramática de descenso recursiva simple, a menudo codificada a mano, mientras que LR (1) generalmente significa un generador de analizadores sintácticos como YACC. Esta parte de la gramática se reduce a tokens (terminales) pero no más abajo.

Los símbolos generalmente se definen por separado utilizando una gramática aún más simple, como una gramática de operador. [Puede buscar estos términos para obtener mejores definiciones de las que puedo dar aquí.] El lexer que lee estos símbolos suele ser responsable de la mayor parte del rendimiento del compilador, por lo que, en mi experiencia, siempre está codificado a mano. LEX es torpe (y solo C) y la expresión regular es demasiado lenta.

El punto es comprender que las reglas de análisis manejan la tecnología necesaria para su analizador, y las reglas de lexing lo mismo para su lexer. La distinción clara entre ellos es si se aplican al uso de tokens (terminales) o la construcción de ellos.

Esto puede no ayudar a su progreso académico, pero es importante si va más allá de los proyectos de juguetes.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.