Este es un analizador PHP en etapa inicial diseñado, desde el principio, para escenarios de uso de IDE (consulte Objetivos de diseño para obtener más detalles). Todavía queda mucho trabajo por hacer, por lo que en este punto, este repositorio sirve principalmente como un experimento y el inicio de una conversación.
Esta es la rama v0.1, que cambia las estructuras de datos para admitir la sintaxis agregada después de la línea de lanzamiento inicial 0.0.x.
Una vez que haya configurado su máquina, puede usar el analizador para generar y trabajar con el árbol de sintaxis abstracta (AST) a través de una API amigable.
<?php// Las clases requeridas de carga automática requieren __DIR__. "/vendor/autoload.php";use MicrosoftPhpParser{DiagnosticsProvider, Node, Parser, PositionUtilities};// Crear una instancia del nuevo analizador instancia$parser = new Parser();// Devolver e imprimir un AST a partir del contenido de la cadena$astNode = $parser ->parseSourceFile('<?php /* comentario */ eco "¡Hola!"');var_dump($astNode);// Obtiene e imprime errores del nodo AST. El analizador maneja los errores con elegancia, // por lo que se puede utilizar en escenarios de uso de IDE (donde el código suele estar incompleto).$errors = DiagnosticsProvider::getDiagnostics($astNode);var_dump($errors);// Recorre todos los descendientes de nodos de $astNodeforeach ($astNode->getDescendantNodes() as $descendiente) {if ($instancia descendiente de NodeStringLiteral) {// Imprime el texto del nodo (sin espacios en blanco ni comentarios)var_dump($dedescendiente->getText());// Todos los nodos se vinculan a sus padres, por lo que es fácil navegar por el árbol.$grandParent = $dedescendiente->getParent()- >getParent();var_dump($grandParent->getNodeKindName());// El AST es totalmente representativo y se puede conectar de ida y vuelta a la fuente original.// Esto permite a los consumidores para crear herramientas confiables de formato y refactorización.var_dump($grandParent->getLeadingCommentAndWhitespaceText()); }// Además de recuperar todos los hijos o descendientes de un Nodo,// Los nodos exponen propiedades específicas del tipo de Nodo.if ($instancia descendiente de NodeExpressionEchoExpression) {$echoKeywordStartPosition = $dedescendiente->echoKeyword->getStartPosition();// Para reducir el consumo de memoria, las posiciones se representan como un único número entero//índice en el documento, pero sus posiciones de líneas y caracteres se pueden identificar fácilmente. recuperado.$lineCharacterPosition = PositionUtilities::getLineCharacterPositionFromPosition($echoKeywordStartPosition,$dedescendiente->getFileContents() );echo "línea: $lineCharacterPosition->línea, carácter: $lineCharacterPosition->carácter"; } }
Nota: la API aún no está finalizada, así que, si tiene problemas con los archivos, háganos saber qué funcionalidad desea exponer y veremos qué podemos hacer. También registre cualquier error con comportamiento inesperado en el árbol de análisis. Todavía estamos en nuestras primeras etapas y cualquier comentario que tenga será muy apreciado.
Diseño tolerante a errores: en escenarios IDE, el código es, por definición, incompleto. En el caso de que se ingrese un código no válido, el analizador aún debería poder recuperarse y producir un árbol válido + completo, así como diagnósticos relevantes.
Rápido y liviano (debería poder analizar varios MB de código fuente por segundo, para dejar espacio para otras funciones).
Estructuras de datos eficientes en memoria
Permitir el análisis incremental en el futuro
Se adhiere a las especificaciones del lenguaje PHP, admite gramáticas PHP5 y PHP7
El AST generado proporciona propiedades (totalmente representativas, etc.) necesarias para las operaciones semánticas y transformacionales, que también deben ser eficaces.
Totalmente representativo y con retorno al texto a partir del cual se analizó (todos los espacios en blanco y comentarios "trivia" se incluyen en el árbol de análisis)
Es posible atravesar fácilmente el árbol a través de nodos padre/hijo
Tiempo de respuesta de la interfaz de usuario <100 ms, por lo que cada operación del servidor de idiomas debe ser <50 ms para dejar espacio para todas las demás cosas que suceden en paralelo.
Simple y fácil de mantener en el tiempo: los analizadores tienden a volverse muy confusos y muy rápidos, por lo que la legibilidad y la capacidad de depuración son una alta prioridad.
Comprobable: el analizador debe producir árboles de análisis demostrablemente válidos. Esto lo logramos definiendo y probando continuamente un conjunto de invariantes sobre el árbol.
API amigable y descriptiva para que otros puedan desarrollarla fácilmente.
Escrito en PHP: haga que sea lo más fácil posible para la comunidad PHP consumir y contribuir.
Para garantizar un nivel suficiente de corrección en cada paso del camino, el analizador se está desarrollando utilizando el siguiente enfoque incremental:
Fase 1: escribir lexer que no admita la gramática PHP, pero admita tokens EOF y desconocidos. Escribe pruebas para todos los invariantes.
Fase 2: soporte de gramática léxica PHP, muchas pruebas
Fase 3: escribir un analizador que no admita la gramática PHP, pero que produzca un árbol de nodos de error. Escribe pruebas para todos los invariantes.
Fase 4: soporte de gramática sintáctica PHP, muchas pruebas
Fase 5 (en progreso): validación y optimización en el mundo real
Corrección: validar que no se produzcan errores en bases de código de muestra, comparar con otros analizadores (investigar cualquier caso de desacuerdo), pruebas difusas
Rendimiento: perfil, punto de referencia frente a grandes aplicaciones PHP
Fase 6: Finalizar la API para que el consumo sea lo más fácil posible para las personas.
Algunas de las construcciones gramaticales de PHP (es decir, expresión de rendimiento y cadenas de plantilla) aún no son compatibles y también hay otros errores varios. Sin embargo, debido a que el analizador es tolerante a errores, estos errores se manejan correctamente y, por lo demás, el árbol resultante está completo. Para tener una idea más holística de dónde nos encontramos, puede ejecutar el conjunto de pruebas de "validación" (consulte Pautas de contribución para obtener más información sobre cómo ejecutar pruebas). O simplemente, eche un vistazo a los resultados de las pruebas de validación actuales.
Aunque todavía no hemos comenzado la etapa de optimización del rendimiento, hasta ahora hemos visto resultados prometedores y tenemos mucho más margen de mejora. Consulte Cómo funciona para obtener detalles sobre nuestro enfoque actual y ejecute las pruebas de rendimiento en su propia máquina para comprobarlo usted mismo.
Objetivos de diseño : conozca los objetivos de diseño del proyecto (características, métricas de rendimiento y más).
Documentación : aprenda cómo hacer referencia al analizador de su proyecto y cómo realizar operaciones en el AST para responder preguntas sobre su código.
Herramienta Visualizador de sintaxis : obtenga una sensación más tangible del AST. Sea creativo: ¡vea si puede romperlo!
Estado actual y enfoque : ¿cuánta gramática se admite? ¿Actuación? ¿Memoria? ¿Estabilidad de API?
Cómo funciona : aprenda sobre la arquitectura, las decisiones de diseño y las compensaciones.
Lexer y analizador
Estrategia de tolerancia a errores
Análisis incremental
Preguntas abiertas
Estrategia de validación
¡Contribuir! - aprenda cómo participar, consulte algunos consejos sobre confirmaciones educativas que le ayudarán a mejorar el código base (incluso si nunca antes ha trabajado en un analizador) y flujos de trabajo recomendados que facilitan la iteración.
Este proyecto ha adoptado el Código de conducta de código abierto de Microsoft. Para obtener más información, consulte las preguntas frecuentes sobre el Código de conducta o comuníquese con [email protected] si tiene alguna pregunta o comentario adicional.