2015-07-03 12 views
11

Piszę makro m(expr: String), gdzie expr jest wyrazem w jakimś języku (nie Scala):Jak odróżnić potrójne cytaty od pojedynczych cudzysłowów w makrach?

m("SOME EXPRESSION") 

m(""" 
    SOME EXPRESSION 
""") 

Kiedy jestem parsowania wyrażenie chciałbym zgłosić komunikaty o błędach z odpowiednich miejscach w pliku źródłowym. Aby to osiągnąć, powinienem znać lokalizację literału literowego i liczbę cytowań literału (3 lub 1). Niestety, nie znaleźliśmy żadnej metody, która zwraca liczbę cytatów dosłowne:

import scala.language.experimental.macros 
import scala.reflect.macros.blackbox.Context 

object Temp { 
    def m(s: String) : String = macro mImpl 

    def mImpl(context: Context)(s: context.Expr[String]): context.universe.Tree = { 
    import context.universe._ 

    s match { 
     case l @ Literal(Constant(p: String)) => 
     if (l.<TRIPLE QUOTES>) { 
      ... 
     } else { 
      ... 
     } 

     case _ => 
     context.abort(context.enclosingPosition, "The argument of m must be a string literal") 
    } 
    } 
} 

Co należy umieścić zamiast <TRIPLE QUOTES>?

+0

Czy próbowałeś dopasować 'l' do wzoru z pojedynczymi znakami i wzorem z potrójnymi qoutami? Zobacz: http://stackoverflow.com/questions/9770416/scala-case-match-partial-string – mpkorstanje

Odpowiedz

3

Jedynym sposobem mogę myśleć o to, aby uzyskać dostęp do pliku źródłowego i sprawdzić potrójnych cudzysłowów:

l.tree.pos.source.content.startsWith("\"\"\"",l.tree.pos.start) 

Trzeba również edytować swoje sprawy Dopasowanie:

case l @ Expr(Literal(Constant(p: String))) => 

Oto wersja z niektóre wyjaśnienia:

val tree: context.universe.Tree = l.tree 
val pos: scala.reflect.api.Position = tree.pos 
val source: scala.reflect.internal.util.SourceFile = pos.source 
val content: Array[Char] = source.content 
val start: Int = pos.start 
val isTriple: Boolean = content.startsWith("\"\"\"",start) 
Powiązane problemy