Pegjs: Foro o chat? ¿Pasando valores hacia abajo / subiendo valores?

Creado en 23 mar. 2017  ·  7Comentarios  ·  Fuente: pegjs/pegjs

pegjs es simple y poderoso. ¡Me encanta! Tengo algunas preguntas que no se tratan en los documentos:

Estoy analizando esto, que funciona, pero la regla parece incómoda:

f = x => x * x

Si lo delego para que diga Operador, no hay forma de transmitir valores. Si creo ValuesOperators yo = y =>, es un poco más limpio, pero en el nivel superior todavía necesito comprobar cuál era. En el ejemplo de JavaScript, veo el uso de {type: "Literal", value: ...}. ¿Es esa la mejor manera de transmitir la información de nuevo?

  = values:Values body:(_ "=>" _ Expression)? assign:(_ "=" _ Expression)? {
      if (body && body.length > 0) {
        return new Function(values, body[3]);
      } else if (assign) {
        return new Assignment(values, assign[3]);
      } else {
        return values;
      }
    }

¡Gracias!
Miguel

Comentario más útil

Supuse que no dar marcha atrás y ser codicioso significaba que tenía que trabajar "dondequiera que esté actualmente", pero ese no es el caso. ¡Hurra!

Codicioso solo quiere decir que si encuentra una coincidencia, la aceptará, ¿correcto? Pero si toda la regla no coincide, comenzará de nuevo desde el principio en la siguiente partida. Esto hace que sea mucho más fácil de lo que estaba tratando de hacer por primera vez.

x, y = 2 + 3.foo + "foo", 5 * 2

Esto es bastante fácil cuando la asignación se puede hacer coincidir por separado de una expresión regular, etc.

  = Assignment
  / Expression

Assignment
  = vars:Variables _ "=" _ expr:Expression

Variables
  = head:Identifier tail:(_ "," _ Identifier)*

...

Todos 7 comentarios

En gramáticas es fundamental comprender las reglas. Y está proporcionando sólo sub ... esto no está claro para mí, ¿cómo puede ser claro para la máquina?
Las gramáticas LALR son muy difíciles de escribir pero más fáciles que LR y más fáciles que LL ..
La gramática PEG es fácil de escribir y la más difícil de escribir de manera eficiente.
¿Estás seguro de que estás usando el juguete adecuado? Si tiene buena gramática de PEG, debería poder crear un transpilador o interpretar tan fácilmente como interpretar sus reglas.

¿Conoce el boxeo / unboxing en máquinas virtuales?

¿Cómo puede tener values en el lado izquierdo de la asignación? porque tienes esto: body:(_ "=>" _ Expression)? terminó con ?

¿Qué significa values en tu gramática? ¿Sabes qué es el valor L ?

Debes mantener tu gramática semánticamente cercana. Es difícil con PEG en algunos casos .. { type: "Literal", value: ... } es exactamente lo que necesita en AST. Mira http://astexplorer.net/ cómo se ve

Acabo de comenzar a usarlo para experimentar, así que sí, algunos de los nombres son incorrectos :) He escrito algunos analizadores simples LL (1), pero ha pasado un tiempo. Solo tengo curiosidad por saber cuál es la mejor manera de manejar las decisiones. Lo simplificaré para esta sintaxis:

a = b
o
x => x * x

¿Es más apropiado hacer algo como esto?

AssignmentOrFunction
= ident: Operador identificador : IdentOperator {
if (operator.type === "Función") {
...
}

IdentOperator
= "="! ">" {return {tipo: "Asignación"; }}
/ "=>" {...}

Para su información, "valores" fue un término que usé para referirme a una lista de elementos; serían valores si se usaran como una tupla, pero variables si se usaran para definir los argumentos de la función. Por ejemplo (2 + 3).

¡Gracias por tu tiempo!

@mikeaustin Está en el tuyo :-)

Escribir gramáticas se trata de reducciones . Lo más superior es la declaración . Es como sentense, ya sabes, tienes gramáticas LL :-)

Es su responsabilidad definir la gramática en sentido (lo siento, tengo problemas con el inglés :-D a veces)

¿Cómo desea procesar AssignmentOrFunction? Esto es básicamente lo mismo que la declaración en muchos idiomas, pero también puede ser un valor R.
Por otro lado

    = "=" !">" { return { type: "Assignment"; } }
    / "=>" { ... }

se puede escribir mejor como

    = "=>" { ... }
    / "=" { return { type: "Assignment"; } }

Puede que me equivoque ... pero parece que rompes tu oración en un fragmento no tan importante. Sin contexto, no es realmente importante lo que evalúes.

Los PEG son realmente difíciles de escribir porque puede escribir fácilmente reglas inalcanzables o puede escribir reglas que robarán su oración y las evaluarán incorrectamente, por lo que si es un principiante, debe tener oraciones a la izquierda y AST requeridos a la derecha todo el tiempo, diez. veces más pruebas automatizadas que reglas gramaticales. Créame, cambia una regla y todo su analizador se romperá.

Y, por supuesto, debería jugar, escribir algo, una y otra vez. No es trivial escribir una calculadora de expresión efectiva con PEG, tenga en cuenta varios niveles de precedencia. PEG es mejor para el análisis sintáctico general.

No me da más contexto en su pregunta, por lo que es muy difícil adivinar lo que realmente quiere construir, pero puedo suponer que debería jugar más con las gramáticas, existe AntLR , una gran herramienta para aprender, GoldParser (LALR) (mi primer juguete :-)), algunos analizadores de la vieja escuela que están bien probados, más eficientes pero divididos en tokenizer / parser (lex y yacc más antiguos, flex y bison más nuevos), muchos puertos de ellos.

PEG parece más simple. Realmente es. Pero siempre será de lo más peligroso ...

Muchas gracias! Oh, encontré el grupo de Google para pegjs, pero no lo noté porque estaba en la sección de desarrollo. Si tengo otras preguntas, definitivamente iré allí.

Sí, la asignación "x = y" es una _ declaración_, pero "x => x * x" puede ser parte de una _ expresión_, así como "x == y", etc. "=" es un caso especial, por lo que es "=>" en el sentido de que no son operadores regulares. Practicaré más y observaré más de cerca los ejemplos. Desearía que hubiera ejemplos que fueran más grandes que la calculadora, pero más pequeños que los otros ejemplos. Tal vez si avanzo puede ser un ejemplo :)

Para mi proyecto, me gustaría escribir un lenguaje simple para transpilar a JS. Los conceptos básicos son métodos externos con alcance léxico (sin parches de mono, como Dylan o CLOS, pero sin métodos múltiples), argumentos de palabras clave, ADT, tal vez incluso tipado estático opcional. "Simple" simplemente significa que todo funciona en conjunto y que hay una sola forma de hacer algo. Hacer algo simple puede ser _difícil_.

Además, existen bibliotecas como adt y multimethods que podrían beneficiarse de la sintaxis nativa. Esos en realidad podrían lograrse con sweet , pero sweet solo puede extender JS, no hacerlo más simple. TypeScript tiene opciones como "--strictNullChecks" y admite tipos de unión en línea, pero nuevamente, extiende JS para que deje todas las cosas malas allí (coacciones implícitas, "+" para concatenación de cadenas, elevación de alcance, etc.).

Una vez más, ¡gracias por toda la ayuda!
Miguel

Supuse que no dar marcha atrás y ser codicioso significaba que tenía que trabajar "dondequiera que esté actualmente", pero ese no es el caso. ¡Hurra!

Codicioso solo quiere decir que si encuentra una coincidencia, la aceptará, ¿correcto? Pero si toda la regla no coincide, comenzará de nuevo desde el principio en la siguiente partida. Esto hace que sea mucho más fácil de lo que estaba tratando de hacer por primera vez.

x, y = 2 + 3.foo + "foo", 5 * 2

Esto es bastante fácil cuando la asignación se puede hacer coincidir por separado de una expresión regular, etc.

  = Assignment
  / Expression

Assignment
  = vars:Variables _ "=" _ expr:Expression

Variables
  = head:Identifier tail:(_ "," _ Identifier)*

...

Los PEG de @mikeaustin tienen opción ordenada, lo que significa que el primer patrón que coincida en una expresión coincidirá automáticamente. El ejemplo de @langpavel es una buena forma de expresar una preferencia por => sobre = . Es posible que desee pensar más en lo que puede ser una expresión en términos de "una de estas cosas" en lugar de "tomar todo este texto que podría ser una expresión y descifrarlo más tarde".

  = FunctionExpression
  / Assignment
  / Value

Para demostrarlo, creé una gramática de prueba con la que puedes jugar. Es un poco ruidoso, pero he tratado de mantenerlo bastante simple, ignorando algunas cosas como permitir espacios en blanco y operadores adicionales. Tenga en cuenta el bloque Expression donde ocurre la magia. Además, he usado cosas como SubExpression y ExpressionList como formas de manejar "muchas de estas" situaciones; ese patrón funciona bien para mí manteniendo los separadores de lista y los elementos separados.

En cada caso, trato de mantener la gramática simple al tener un elemento para cada tipo de coincidencia. Hay algo de redundancia involucrada porque podría reescribirlo de tal manera que tengamos una gran secuencia de coincidencia con todas las combinaciones posibles, pero eso es difícil de seguir y razonar y deja una ambigüedad abierta que los PEG pueden eliminar con una elección ordenada. Espero eso ayude.

Echaré un vistazo a la gramática de la prueba, ¡gracias! Es útil ver un subconjunto mínimo de un idioma, ya que la gramática de JavaScript es bastante grande.

@dmsnell He aprendido mucho últimamente eliminando reglas y agregando algunas nuevas a la gramática de JavaScript. Puedes ver la última aquí: impulse.pegjs . Eliminé la sintaxis de elisión [,,], algunos operadores, expresiones de secuencia, etc. y agregué sintaxis de tupla (1, 2) y sintaxis de rango 1..5. Los números de coma flotante requieren un decimal en ambos lados para facilitar el análisis de los rangos literales.

Últimamente he estado trabajando en gran parte del tiempo de ejecución, pero quiero volver al analizador para emitir JavaScript. Estoy entre trabajos, así que tengo un poco de tiempo en mis manos :) Algunas ideas para un dialecto limpio de JavaScript con métodos de extensión, parámetros con nombre, rasgos y mixins, sobrecarga de operadores y tupla literal y sintaxis de rango.

¡Gracias de nuevo!
Miguel

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

richb-hanover picture richb-hanover  ·  7Comentarios

dmajda picture dmajda  ·  15Comentarios

mattkanwisher picture mattkanwisher  ·  5Comentarios

audinue picture audinue  ·  13Comentarios

futagoza picture futagoza  ·  13Comentarios