2012-08-31 4 views
9

Ho una grammatica JavaScript ANTLR (presa da Internet), che sembra supportare tutto tranne i regex letterali.Analisi su JavaScript regex con ANTLR

Il problema con una regex letterale è che si hanno due regole, essenzialmente:.

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

e

regexLiteral 
    : '/' RegexLiteralChar* '/' 

dove la regola RegexLiteralChar utilizza diverse regole lexer di un'espressione normale (ad esempio, un la doppia citazione non lo termina).

Ciò significa che ho bisogno, in qualche modo, di modificare una sorta di stato lexer dal mio parser. Come posso fare questo? È possibile?

+1

comunicazione tra parser e le regole lessiche non sono possibili. Forse date un'occhiata a questa grammatica, che sembra gestire regex-letterali: http://research.xebic.com/es3/ (controllate il file ZIP). –

risposta

5

Guardando la grammatica menzionato nel commento di Bart Kiers here, si può vedere questo commento,

Le principali sfide affrontate nella definizione di questa grammatica sono:

-1- L'ambiguità che circonda la DIV firmare in relazione all'espressione moltiplicativa e all'espressione regolare letterale. Questo è risolto con un po 'di magia guidata da lexer: un predicato semantico gated attiva o disattiva il riconoscimento delle espressioni regolari, in base al valore della proprietà RegularExpressionsEnabled. Quando sono abilitate le espressioni regolari , hanno la precedenza sulle espressioni della divisione . La decisione se le espressioni regolari sono abilitate è in base all'euristica che il token precedente può essere considerato come ultimo token di un operando di una divisione a sinistra come .

...

funzione

L'areRegularExpressionsEnabled() è definito come,

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; 
    } 
} 

E poi la funzione viene usato nell'espressione RegularExpressionLiteral,

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