[Blanco] Serie 7 para crear un compilador de lenguaje Anltr la reconstrucción de secuencias de comandos

sintaxis de la expresión

sintaxis de la expresión, se refiere a la clave: blanco para crear un compilador Serie 4] para asegurarse de que la expresión correcta de las prioridades, y la asociatividad de la recursión por la izquierda , que resumen y explican.

Antlr puede resolver automáticamente recursión por la izquierda problema, por lo que al escribir expresiones regulares, no se preocupe acerca de si o posterior en un bucle infinito. Pero de esta manera, aún tenemos que escribir una regla para cada operación, escribir una operación lógica terminó la adición, la adición de la multiplicación terminado de escribir, a fin de lograr la  prioridad de apoyo, o algunos problemas. En este momento, Antlr nos puede ayudar aún más, en la mayor parte de forma concisa a la precedencia y asociatividad de soporte de expresión.   

expression
    : primary
    | expression bop='.'
      ( IDENTIFIER
      | functionCall
      | THIS
      )
    | expression '[' expression ']'
    | functionCall
    | expression postfix=('++' | '--')
    | prefix=('+'|'-'|'++'|'--') expression
    | prefix=('~'|'!') expression
    | expression bop=('*'|'/'|'%') expression  
    | expression bop=('+'|'-') expression 
    | expression ('<' '<' | '>' '>' '>' | '>' '>') expression
    | expression bop=('<=' | '>=' | '>' | '<') expression
    | expression bop=INSTANCEOF typeType
    | expression bop=('==' | '!=') expression
    | expression bop='&' expression
    | expression bop='^' expression
    | expression bop='|' expression
    | expression bop='&&' expression
    | expression bop='||' expression
    | expression bop='?' expression ':' expression
    | <assoc=right> expression
      bop=('=' | '+=' | '-=' | '*=' | '/=' | '&=' | '|=' | '^=' | '>>=' | '>>>=' | '<<=' | '%=')
      expression
    ;

El código incluye la casi totalidad de las reglas de expresión.

Así que no pudo sostener la ventaja de que? Por la prioridad original de orden de las diferentes producciones decisión correcta . En la gramática libre de contexto estándar, el orden de producción no es relevante, pero en el algoritmo específico, será determinado con el fin de intentar la producción individual.

¿Cómo apoyar enlazándolo? En el archivo de sintaxis, Antlr para hacer expresiones de asignación <= Assoc derecha> propiedad marcada, lo que indica expresión de asignación es la combinación correcta. Si no marcada, se asociativo por la izquierda, a Antlr se dio cuenta!

A través de este algoritmo simplificado, AST se simplifica con éxito, ya no tienen una variedad de diferentes Además nodo nodo, multiplicación nodos, etc., sino como un nodo de expresión unificada. Usted puede preguntar: " Si el nodo de expresión son la misma, cómo distinguir donde el analizador ¿Cómo saben qué nodo es el área de hacer la adición o la multiplicación de ella ?? "

En pocas palabras, podemos ver el nodo actual no tiene un operador de emergencia . Por ejemplo, si las operaciones se producen o Token ( "||"), se realiza una operación lógica OR, y la sintaxis dentro BOP =, postfix =, prefix = estas propiedades, algunos operadores como un alias de Token, se expresarán nodo de tipo de atributo. Al consultar el valor de estas propiedades, se puede determinar rápidamente el tipo de la operación actual.

tipos de sintaxis de las declaraciones

La misma expresión como una regla declaración puede ser usada para cubrir todo tipo de declaraciones , incluyendo la sentencia if, para el lazo, mientras sentencias de bucle, estados de conmutación, las declaraciones de retorno y así sucesivamente. Añadir un punto y coma después de una expresión, sino también una declaración, llamada la declaración de la expresión.

statement
    : blockLabel=block
    | IF parExpression statement (ELSE statement)?
    | FOR '(' forControl ')' statement
    | WHILE parExpression statement
    | DO statement WHILE parExpression ';'
    | SWITCH parExpression '{' switchBlockStatementGroup* switchLabel* '}'
    | RETURN expression? ';'
    | BREAK IDENTIFIER? ';'
    | SEMI
    | statementExpression=expression ';'
    ;

La sentencia if

Normalmente, si-else estructura declaración es el siguiente:

if (condition)
  做一件事情;
else
  做另一件事情;

Más a menudo, sin embargo, si-else es con llaves.

if (condition){
  做一些事情;
}
else{
  做另一些事情;
}

Su regla gramatical es la siguiente:

statement : 
          ...
          | IF parExpression statement (ELSE statement)? 
          ...
          ;
parExpression : '(' expression ')';

Usamos el IF y ELSE dos palabras clave, sino también reutilizar una declaración buena y las reglas se han definido reglas de expresión.

Pero si la gente no lo hacen declaración preocupación también lugares como implicará  gramaticales ambiguas  cuestiones.

Resolver la gramática ambigua

Cuando aprendemos un lenguaje de programación, mencionar si la declaración podría mencionar en particular el caso de anidado si las declaraciones y demás suspensión, tales como el código siguiente:

if (a > b)
if (c > d)
做一些事情;
else
做另外一些事情;

En el código anterior, deliberadamente anulando el guión. Una vez que haya escrito las reglas de la gramática no es lo suficientemente bueno, es posible formar la ambigüedad , es decir, utilizando las mismas reglas de sintaxis se puede deducir a partir de dos frases diferentes, o que generan dos AST diferente . Esta gramática se llama gramática ambigua, este enfoque como la siguiente:

stmt -> if expr stmt
      | if expr stmt else stmt
      | other

De acuerdo con esta reglas de sintaxis, primer uso o la primera derivación de la fórmula para producir la segunda producción utilizando la derivación, será diferente AST. AST árbol de la izquierda, más si se combina con el segundo; AST árbol a la derecha, más si se combina con la primera.

Por lo tanto, hay una manera de escribir la ambigüedad gramatical no es así? Sí, por supuesto.

stmt -> fullyMatchedStmt | partlyMatchedStmt
fullyMatchedStmt -> if expr fullyMatchedStmt else fullyMatchedStmt
                   | other
partlyMatchedStmt -> if expr stmt
                   | if expr fullyMatchedStmt else partlyMatchedStmt

De acuerdo con las reglas de la gramática anterior, sólo hay un modo de derivación, que sólo puede generar un AST único:

PartlyMatchedStmt regla sólo se puede aplicar al analizar la primera sentencia if, al resolver la segunda sentencia if es fullyMatchedStmt normas aplicables solamente.

En este momento, sabemos que puede ser resuelto gramática ambigua reescribiendo las reglas de la gramática . En cuanto a la forma de escribir las reglas, que no tiene tan claro a la izquierda rutina recursiva, pero puede ser la experiencia más madura para referencia.

Antlr sintaxis no parece complicado, ¿cómo podemos asegurar problema de ambigüedad que no se produce?

Tal como se utiliza al analizar la gramática es Antlr  algoritmo de LL . LL algoritmo es un primero en profundidad  algoritmo, por lo que al analizar la primera declaración, se va a construir el siguiente nivel si el nodo, el siguiente nodo en una cláusula más va a analizar a cabo. Si no lo hace Antlr LL algoritmo producirá ambigüedad.

para la declaración

los que estén escritos en general, el siguiente aspecto:

for (int i = 0; i < 10; i++){
  println(i);
}

reglas de sintaxis relacionadas son los siguientes:

statement : 
         ...
          | FOR '(' forControl ')' statement
         ...
          ;

forControl 
          : forInit? ';' expression? ';' forUpdate=expressionList?
          ;

forInit 
          : variableDeclarators 
          | expressionList 
          ;

expressionList
          : expression (',' expression)*
          ;

Visto desde las reglas de la gramática anterior, para la instrucción en el análisis final se realiza declaraciones, expresiones y declaraciones de variables constituido. Código de declaración, AST formó después de interpretar de la siguiente manera:

intérprete de comandos de actualización con el modo de Vistor

Estamos preparados a mano intérprete de lenguaje de script, con un método de evaluar () para recorrer todo el árbol de arriba a abajo . A medida que más y más la gramática a procesar, la cantidad de código en este método será cada vez más grande, no es fácil de mantener.

El patrón de diseño del visitante para cada nodo AST, habrá un enfoque separado para tratar, puede hacer que el código más claro y más fácil de mantener.

resumen

  • Antlr automáticamente puede manejar el caso recursivo izquierda. procesando simultáneamente orden de prioridad del problema de acuerdo con la sintaxis de reglas de diferentes producciones. Mientras tanto, denotado por atributo <= Assoc derecha> para abordar el problema de la unión.
  • if-else puede producir ambigüedad. El llamado ambigüedad se refiere a la exportación de dos estructuras gramaticales diferentes con un pushdown regla gramatical para producir dos AST diferente. Podemos ser resueltos mediante la modificación de las reglas de la moda. (Por supuesto, la necesidad de hacer referencia a algunas de las mejores prácticas)
  • En realidad, hay tres para composición de bucle: componentes forInit, de expresión y de declaración.

Curso de referencia: "El tiempo Geek - compilador teoría de la belleza." de gran maestro Gong! 

Publicado 62 artículos originales · ganado elogios 34 · Vistas a 20000 +

Supongo que te gusta

Origin blog.csdn.net/weixin_41960890/article/details/105263228
Recomendado
Clasificación