2012-08-31 24 views
9

ile ben düzenli ifade değişmezleri hariç her şeyi destekliyor gibi görünüyor (internetten alınan) bir ANTLR JavaScript dilbilgisi var.Ayrıştırma JavaScript düzenli ifade antlr

değişmez bir regex ile sorun aslında iki kural, sahip olmasıdır.

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

ve kural RegexLiteralChar normal ifadenin farklı lexer kurallarını kullanır

regexLiteral 
    : '/' RegexLiteralChar* '/' 

(ör çift ​​alıntı onu sonlandırmaz).

Bu

Ben, bir şekilde, benim ayrıştırıcı gelen lexer devlet çeşit değiştirmeniz gerekiyor demektir. Bunu nasıl yapabilirim? Bu mümkün mü? Bart Kiers here tarafından yorumunda belirtilen dilbilgisi baktığımızda

+1

İletişim ve lexer kuralları mümkün değildir. Belki regex-literals ele alan bu dilbilgisine bir göz atın: http://research.xebic.com/es3/ (ZIP dosyasını kontrol edin). –

cevap

5

, sen bu gramer tanımlanmasında karşılaşılan

önemli zorluklar Bu yorumu görebilirsiniz idi:

-1- Belirsizlik DIV çevreleyen Çoğullayıcı ifadeye ve normal ifade değişmezine göre oturum açın. Bu, bazı lexer tahrik büyü ile çözülür: Bir kapı semantik yüklem RegularExpressionsEnabled özelliğinin değerine dayalı, açık veya kapalı normal ifadeler tanınmasını döner. Düzenli ifadeler etkinleştirildiğinde onlar bölümünde ifadeler önceliklidir. Düzenli ifadelerin etkin olup olmadığına dair karar, önceki jetonun, bir bölümün sol taraftaki bir işleneninin son jetonu olarak olarak kabul edilebileceği sezgisel temelli olarak şeklindedir.

...

areRegularExpressionsEnabled() işlevi olarak tanımlanmaktadır

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

ve sonra işlev RegularExpressionLiteral ifadesinde kullanılan

, ayrıştırıcı arasında

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