Ejercicio: Gramática de la versión Inicial de Egg
En este ejercicio te propongo un proceso inverso.
Partiendo del código (opens in a new tab)
que está en la rama inicial
de este repo (opens in a new tab),
sabiendo que el algoritmo de análisis es un PDR,
intenta describir formalmente la gramática
que acepta.
Este es el código inicial implicado:
function parseExpression(program) {
program = skipSpace(program);
var match, expr;
if (match = /^"([^"]*)"/.exec(program)) {
expr = {type: "value", value: match[1]};
} else if (match = /^\d+\b/.exec(program)) {
expr = {type: "value", value: Number(match[0])};
} else if (match = /^[^\s(),"]+/.exec(program)) {
expr = {type: "word", name: match[0]};
} else {
throw new SyntaxError(`Unexpect syntax: ${program}`);
}
return parseApply(expr, program.slice(match[0].length));
}
function skipSpace(string) {
return string.slice(/^(\s|#.*)*/.exec(string)[0].length);
}
function parseApply(expr, program) {
program = skipSpace(program);
if (program[0] != '(') {
return {expr: expr, rest: program};
}
program = skipSpace(program.slice(1));
expr = {type: 'apply', operator: expr, args: []};
while (program[0] != ')') {
var arg = parseExpression(program);
expr.args.push(arg.expr);
program = skipSpace(arg.rest);
if (program[0] == ',') {
program = skipSpace(program.slice(1));
} else if (program[0] != ')') {
throw new SyntaxError("Expected ',' or ')'");
}
}
return parseApply(expr, program.slice(1));
}
¿Que resultados dan estas ejecuciones?
Ejecútalo con las entradas que te propongo abajo. Para cada una de las ejecuciones ten en cuenta estos puntos:
- Antes de hacer la ejecución decide si la entrada es sintácticamente correcta,
- Si es semánticamente correcta
- Cual será la salida
- Una vez que se ha ejecutado:
- Si da error mira en que función ocurre. ¿Es un error sintáctico o semántico? ¿Es lo que esperabas?
- Si no se produce error y crees que debería producirse ¿Que código es el que tienes que modificar?
Entradas:
$ node egg.js 'print(+)'
$ node egg.js 'print(4,)'
$ node egg.js '8()'
$ node egg.js '"hello"(2,3)'
$ node egg.js '+()'
$ node egg.js '+(2,)'