2012-08-31 18 views
9

Tengo una gramática ANTLR de JavaScript (tomada de Internet), que parece ser compatible con todo excepto con los literales de expresiones regulares.Análisis de JavaScript de expresiones regulares con ANTLR

El problema con una expresión regular literal es que tiene dos reglas, esencialmente:.

multiplicativeExpression 
    : unaryExpression (LT!* ('*' | '/' | '%')^ LT!* unaryExpression)* 

y

regexLiteral 
    : '/' RegexLiteralChar* '/' 

donde el RegexLiteralChar regla utiliza diferentes reglas analizadoras que una expresión normal (por ejemplo, una la comilla doble no la termina).

Esto significa que necesito, de alguna manera, cambiar algún tipo de estado lexer de mi analizador. ¿Cómo puedo hacer esto? ¿Es posible?

+1

La comunicación entre analizador y las reglas lexer no son posibles. Tal vez eche un vistazo a esta gramática, que parece manejar literal-regex: http://research.xebic.com/es3/ (verifique el archivo ZIP). –

Respuesta

5

En cuanto a la gramática se menciona en el comentario por Bart Kiers here, se puede ver este comentario,

Los principales desafíos que enfrentan en la definición de esta gramática fueron:

-1- ambigüedad que rodea el DIV firmar en relación con la expresión multiplicativa y la expresión regular literal. Esto es resuelto con alguna magia dirigida por lexer: un predicado semántico cerrado activa o desactiva el reconocimiento de expresiones regulares, basado en el valor de la propiedad RegularExpressionsEnabled. Cuando las expresiones regulares están habilitadas, tienen prioridad sobre las expresiones de división . La decisión de si las expresiones regulares están habilitadas es basándose en la heurística de que el token anterior se puede considerar como último token de un operando del lado izquierdo de una división.

...

función

El areRegularExpressionsEnabled() se define como,

private final boolean areRegularExpressionsEnabled() 
{ 
    if (last == null) 
    { 
     return true; 
    } 
    switch (last.getType()) 
    { 
    // identifier 
     case Identifier: 
    // literals 
     case NULL: 
     case TRUE: 
     case FALSE: 
     case THIS: 
     case OctalIntegerLiteral: 
     case DecimalLiteral: 
     case HexIntegerLiteral: 
     case StringLiteral: 
    // member access ending 
     case RBRACK: 
    // function call or nested expression ending 
     case RPAREN: 
      return false; 
    // otherwise OK 
     default: 
      return true; 
    } 
} 

Y entonces la función se utiliza en la expresión RegularExpressionLiteral,

RegularExpressionLiteral 
    : { areRegularExpressionsEnabled() }?=> DIV RegularExpressionFirstChar RegularExpressionChar* DIV IdentifierPart* 
    ; 
Cuestiones relacionadas