Desde Lenguajes de Infijo a EVM usando Nearley.js
Descripción
Usando Nearley.js describa un lenguaje de programación sencillo (Sintáxis convencional a la Lua/C/BASIC/…). Las acciones semánticas deben retornar ASTs que puedan ser usados por su intérprete del lenguaje Egg.
En el repositorio fun-lang puede encontrar un ejemplo que contiene un pequeño lenguaje escrito en Nearley.js y que se corresponden con la lista de YouTube de Toby Ho Make your ow Language.
Mi consejo es que parta de este repo y modifique el AST producido para que sea el que hemos usado en el lenguaje Egg.
He escrito un pequeño módulo npm moo-ignore que es un wrapper alrededor de moo que es compatible con Nearley.js y provee la forma de ignorar tokens. Puede usarlo para facilitar la escritura de esta práctica.
Requisitos
El lenguaje debe tener:
- Declaraciones (aunque no tiene que ser necesariamente tipeado). Esto es, deberían poder declararse objetos como variables, constantes y funciones
- Sentencias
if
, condiciones
comoa <= b
,asignaciones
,- Alguna forma de bucle,
funciones
y llamadas a funciones,- Arrays,
- Acceso a los elementos de un array y
- Asignación a los elementos de un array.
Gramáticas de Ejemplo
De mas simple a mas complejas:
Fun-Lang
En el repositorio fun-lang puede encontrar un ejemplo que contiene un pequeño lenguaje escrito en Nearley.js y que se corresponden con la lista de YouTube de Toby Ho Make your ow Language.
Tini-C
Escrita en C usando un PDR:
- Tiny-C
- Un subconjunto hiper-minimal de C con un compilador y una VM escritas en C.
- Contiene un lexer
- Un parser PDR que construye un AST
- Un generador de código para una VM
- Un intérprete para la VM
Tiny-BASIC
Gramática en la Wikipedia:
- Tiny Basic. Muy sencillo
Niklaus Wirth PL/0
- Niklaus Wirth’s PL/0 in the Wikipedia. Sencillo.
Lua
Lua es un lenguaje profesional y sin embargo tiene una gramática bastante sencilla. Otra razón para animarse con este lenguaje es que ya tiene una gramática de la que partir en el directorio de ejemplos de Nearley.js:
- Lua grammar inside the Examples folder in nearley.js. Menos de 200 líneas.
Puede partir de este código y simplificarlo para que no lleve tanto trabajo.
Este es un fragmento de programa en Lua:
function maximum (a)
local mi = 1 -- maximum index
local m = a[mi] -- maximum value
for i,val in ipairs(a) do
if val > m then
mi = i
m = val
end
end
return m, mi
end
print(maximum({8,10,23,12,5})) --> 23 3
Para saber más sobre Lua consulte:
- Learning Lua: http://www.lua.org/pil/contents.html
- Lua manual https://www.lua.org/manual/5.1/es/manual.html
Mini Pascal en Python
- mini-pascal.
- Syntax of Mini-Pascal
- Mini Pascal Compiler in Python
- Gramática
- Un posible estrategia para esta práctica es empezar con PL/0 e ir haciendo crecer el lenguaje hasta convertirlo en Mini Pascal.
ANSI C Grammar in Parse::Eyapp
Aqui tiene una gramática del lenguaje C escrita en Parse::Eyapp, una herramienta de generación de analizadores sintácticos para el lenguaje Perl que desarrollé hace muchos años:
Pascal
JavaScript
- Acorn un compilador de JS descendente recursivo:
- Gramática de JS en PEGjs
Python
Ruby
- ruby18.y Yacc grammar at GitHub Ruby repo
- Ruby Grammar at www.cse.buffalo.edu
Java
Infix program examples
Sigue un ejemplo de como podría ser su lenguaje:
begin
# array is an egg function that returns an array
let result = call array(2, 3, 4, 5);
# print is also egg function
call print(result);
# We can also access array properties
call print("Array length: " + result.length);
# And call array methods
let string = call result.join(" ~ ");
call print(string);
# We can use array map method by passing an anonymous function as argument
let doubles = call result.map(func(x, i, a) begin
x * 2
end);
call print(doubles)
end
Y el resultado de una ejecución del anterior programa
bin/infix2egg.js --run examples/arrays.inf
[ 2, 3, 4, 5 ]
Array length: 4
2 ~ 3 ~ 4 ~ 5
[ 4, 6, 8, 10 ]
Use su módulo Egg
Como tenemos publicado en github-registry nuestro intérprete egg lo usaremos en nuestro compilador del lenguaje infijo que hemos diseñado para interpretar los ASTs
Rúbrica
Incidencias para el Project Board para la prácticaDesde Lenguajes de Infijo a EVM usando Nearley.js
-
El lenguaje tiene al menos:
Declaraciones (aunque no tiene que ser necesariamente tipeado). Esto es, deberían poder declararse objetos como variables, constantes y funciones
Sentencias
if
,Condiciones como
a <= b
,Asignaciones,
Alguna forma de bucle,
Funciones y llamadas a funciones,
Arrays, - Acceso a los elementos de un array y - Asignación a los elementos de un array.
A valorar: La expresividad y potencia del lenguaje
Se ha hecho un análisis léxico separado y limpio
Retorna ASTs Egg correctos
Se pueden ejecutar los
.evm
generados fácilmenteOpcional: se traduce a JS fácilmente