# egg-parser
# Objetivos
Usando el generador de analizadores Nearley.js escriba un parser para el lenguaje Egg que genere los árboles según la especificación que se describe en la sección ASTs: Árboles de Análisis Abstracto. Utilice el generador de analizadores léxicos moo-ignore para la fase de análisis léxico.
Construya un paquete npm y
publíquelo en GitHub Registry con ámbito @ull-esit-pl-2223
y nombre el nombre del repo asignado.
El módulo exportará un objeto con al menos la propiedad { parseFromfile }
.
parseFromFile(inputFile)
es una función que devuelve el AST construído a partir de los contenidos del programa en lenguaje Egg contenido en el fichero con nombreinputFile
La gramática del lenguaje Egg se describe en la sección Gramáticas Independientes del Contexto. This is the equivalent syntax diagram:
expression
applies
Se deberá proveer un ejecutable eggc
con una interfaz como esta:
➜ prefix-lang git:(master) ✗ bin/eggc.js -h
Usage: eggc [options] <origin>
Compile a Egg lang file
Arguments:
origin The path of the file to compile
Options:
-V, --version output the version number
-o, --out <destination> Path for output file. If it isn't specified the path of the origin file will be
used,changing the extension to .json
-h, --help display help for command
2
3
4
5
6
7
8
9
10
11
12
13
Puede usar el ejecutable evm
(las siglas corresponden a Egg virtual Machine) del paquete "@crguezl/eloquentjsegg" (opens new window) para comprobar que los ASTs generados funcionan.
Sigue un ejemplo (compatible "@crguezl/eloquentjsegg" (opens new window) versión 1.2.6) de como debería funcionar nuestro parser eggc
:
➜ prefix-lang git:(master) ✗ cat test/examples/array.egg
do(
def(x, arr(arr(1,4),5,7)),
print([](x,0)), # [1,4]
print([](x,1)) # 5
)
2
3
4
5
6
Nuestro parser deberà por tanto producir un AST conforme a la especificación dada en la sección Anatomía de los AST para Egg. Esto es, deberá estar conforme a esta gramática árbol:
ast: VALUE
| WORD
| APPLY( operator:WORD args:[ ast * ]))
2
3
Los nodos APPLY
tienen dos atributos operator
y args
. El atributo args
es un ARRAY conteniendo los ASTs que se corresponden con los argumentos de operator
. Los nodos WORD
son nodos hoja y tienen al menos el atributo name
.
Los nodos VALUE
tienen al menos el atributo value
.
Por ejemplo, el AST para +(a,*(4,5))
se podría describir mediante este término:
APPLY(
operator: WORD{name: +},
args: [
WORD{name: a},
APPLY(
operator: WORD{name:*},
args: [VALUE{value:4}, VALUE{value:5}]
)
]
)
2
3
4
5
6
7
8
9
10
A la derecha del tipo de nodo y entre llaves escribimos las parejasatributo: valor
que nos interesa resaltar.
El ejecutable bin/eggc.js
deberá producir un fichero JSON con el ast:
✗ bin/eggc.js test/examples/array.egg -o test/ast/array.json
Puede ver los contenidos del ast para el ejemplo test/examples/array.egg (opens new window) haciendo click sobre este enlace:
➜ prefix-lang git:(master) ✗ cat test/ast/array.json
A continuación podemos usar el ejecutable evm
para interpretar el árbol:
➜ prefix-lang git:(master) ✗ npx evm test/ast/array.json
[ 1, 4 ]
5
2
3
Observe que puesto que el paquete "@crguezl/eloquentjsegg" (opens new window) ha sido instalado localmente, necesitamos hacer uso de npx (opens new window) para ejecutar el intérprete evm
.
npx
npx <command>[@version] [command-arg]...
executes <command>
either from a local node_modules/.bin
, or
from a central cache, usually in ~/.npm/cacache
npm config get cache
/Users/casianorodriguezleon/.npm
✗ ls /Users/casianorodriguezleon/.npm/_cacache
content-v2 index-v5 tmp
2
3
4
installing any packages needed in order for <command>
to run. By default, npx
will check whether <command>
exists in $PATH
, or in the local project binaries, and execute that. If <command>
is not found, it will be installed prior to execution.
En el directorio node_modules/@crguezl/eloquentjsegg/examples
tiene algunos ejemplos de programas egg que puede usar para comprobar el buen funcionamiento de su parser:
➜ prefix-lang git:(master) ✗ ls node_modules/@crguezl/eloquentjsegg/examples
array.egg greater-x-5.egg main2.js one.egg sum.egg unbalanced.egg
expcomma.egg if.egg one-err-2.egg scope.egg sum.egg.evm
fun.egg main.js one-err.egg string.egg two.egg
2
3
4
Nota de Advertencia
En algunos de los ejemplos, vídeos, repos, etc. que acompañan esta práctica puede notar algunas
inconsistencias en el lenguaje Egg debidas a que casi en cada curso hemos ido haciendo alias de algunos de los nombres de los constructos. Por ejemplo, a veces en un vídeo en vez de fun
usamos ->
y en algún ejemplo en los apuntes en vez de element
se usa <-
, etc. También en algún ejemplo aparecen llavitas {
y }
en vez de paréntesis (de nuevo una llave aquí es un alias del correspondiente paréntesis). Son cambios triviales que no deberían afectar a la comprensión del texto.
# Publicación del módulo
Una parte de los conceptos y habilidades a adquirir con esta práctica se explican en la sección Creating and publishing a node.js module en GitHub y en NPM. Léala con detenimiento antes de hacer esta práctica.
# Pruebas
Deberá añadir pruebas usando Mocha y Chai o Jest. Repase las secciones Testing with Mocha and Chai y Jest.
Añada un estudio de covering. See the notes in covering.
Añada CI con GitHub Actions.
# Informe y Documentación
Documente
el módulo incorporando un README.md
: Como se instala, como se usa el ejecutable, como se carga la librería, etc.
Use GitHub Pages en el directorio docs
.
No haga el informe de la práctica en el README.md
sino que utilice el generador estático Vuepress (opens new window) para hacer el informe.
Para el despliegue (opens new window) del informe puede
mover los ficheros generados por VuePress del directorio
src/.vuepress/dist/
al directoriodocs/
).Recuerde poner
base
en su Vuepressconfig.js
con el nombre de su repo. Algo así:module.exports = { title: 'Lab egg-parser Report', base: '/egg-parser-casiano-rodriguez-leon-alumno5/', ... }
1
2
3
4
5Añada un fichero con nombre
.nojekyll
(opens new window) en su directoriodocs/
.
La documentación de la API de la función exportada usando JsDoc la puede dejar accesible en el despliegue (directorio docs/api
) o puede tratar de integrarla con Vuepress JsDoc Plugin (opens new window).
Añada el informe de Covering también (directorio docs/covering
o similar).
# Challenge
- Asegúrese de producir mensajes de error significativos informando de los números de línea y columna correctos
# References
# Nearley.js
# moo
# Testing
# Documentation
- Vuepress (opens new window)
- .nojekyll (opens new window) Bypassing Jekyll on GitHub Pages
- JSDoc and others in this notes