Pregunta

He estado reflexionando sobre la creación de un lenguaje que sería extremadamente adecuado para la creación de DSL, al permitir definiciones de funciones que son infijo, postfix, prefijo o incluso consisten en varias palabras. Por ejemplo, podría definir un operador de multiplicación infijo de la siguiente manera (donde la multiplicación (X, Y) ya está definida):

a * b => multiply(a,b)

O un postfix " al cuadrado " operador:

a squared => a * a

O un operador ternario de estilo C o Java, que involucra dos palabras clave intercaladas con variables:

a ? b : c => if a==true then b else c

Claramente, existe un amplio margen para las ambigüedades en dicho lenguaje, pero si se escribe estáticamente (con inferencia de tipos), entonces la mayoría de las ambigüedades podrían eliminarse, y las que quedan podrían considerarse un error de sintaxis (para ser corregido por agregar corchetes cuando corresponda).

¿Hay alguna razón por la que no veo que haga que esto sea extremadamente difícil, imposible o simplemente una mala idea?

Editar: Varias personas me han señalado idiomas que pueden hacer esto o algo así, pero en realidad estoy interesado en los consejos sobre cómo podría implementar mi propio analizador para ello, o problemas que podría encontrar si lo hago.

¿Fue útil?

Solución

Esto no es demasiado difícil de hacer. Deberá asignar a cada operador una fijación (infijo, prefijo o postfix) y una precedencia . Convierta la precedencia en un número real; me lo agradecerás luego. Los operadores de mayor precedencia se unen más estrechamente que los operadores de menor precedencia; en niveles iguales de precedencia, puede requerir desambiguación con paréntesis, pero probablemente prefiera permitir que algunos operadores sean asociativos para que pueda escribir

x + y + z

sin paréntesis. Una vez que tenga una fijación, una precedencia y una asociatividad para cada operador, querrá escribir un analizador de precedencia de operador . Este tipo de analizador es bastante simple de escribir; escanea tokens de izquierda a derecha y usa una pila auxiliar. Hay una explicación en el libro del dragón, pero nunca la he encontrado muy clara, en parte porque el libro del dragón describe un caso muy general de análisis de precedencia de operador. Pero no creo que le resulte difícil.

Otro caso del que querrás tener cuidado es cuando tienes

prefix (e) postfix

donde prefix y postfix tienen la misma precedencia. Este caso también requiere paréntesis para la desambiguación.

Mi artículo Análisis de expresiones con operadores de prefijo y postfijo tiene un analizador de ejemplo en la parte posterior, y puede descargar el código, pero está escrito en ML, por lo que su funcionamiento puede no ser obvio para el aficionado. Pero todo el negocio de la fijación y demás se explica con gran detalle.

Otros consejos

¿Qué vas a hacer sobre el orden de las operaciones?

a * b squared

Es posible que desee consultar Scala, que tiene una especie de enfoque único para operadores y métodos.

Haskell tiene justo lo que estás buscando.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top