Supongamos que estoy escribiendo un analizador sintáctico de SQL rudimentario en Scala. Tengo el siguiente:coincidencia no codiciosa en Scala RegexParsers
class Arith extends RegexParsers {
def selectstatement: Parser[Any] = selectclause ~ fromclause
def selectclause: Parser[Any] = "(?i)SELECT".r ~ tokens
def fromclause: Parser[Any] = "(?i)FROM".r ~ tokens
def tokens: Parser[Any] = rep(token) //how to make this non-greedy?
def token: Parser[Any] = "(\\s*)\\w+(\\s*)".r
}
Al tratar de igualar selectstatement contra SELECT foo FROM bar
, ¿cómo puedo evitar la selectclause de engullir toda la frase debido a la rep(token)
en ~ tokens
?
En otras palabras, ¿cómo especifico la coincidencia no codiciosa en Scala?
Para aclarar, soy plenamente consciente de que puedo usar la sintaxis estándar no codiciosa (*?) O (+?) Dentro del patrón String, pero me pregunto si hay una forma de especificarlo en un nivel superior dentro def tokens. Por ejemplo, si yo hubiera definido token de la siguiente manera:
def token: Parser[Any] = stringliteral | numericliteral | columnname
Entonces, ¿cómo puedo especificar coincidencia no expansivo para el representante (token) en el interior fichas def?
Parece que estamos tratando [con la característica de PEG] (https://en.wikipedia.org/wiki/Parsing_expression_grammar#Operational_interpretation_of_parsing_expressions) aquí: Mientras comparadores de expresiones regulares pueden comenzar haciendo coincidir con avidez, pero luego dar marcha atrás y pruebe coincidencias más cortas si fallan y CFG intenta todas las posibilidades, los operadores '*', '+' y '' 'de PEG siempre se comportan con avidez, consumiendo la mayor cantidad de información posible y nunca retrocediendo: la expresión' a * 'siempre consumirá muchas a's están disponibles consecutivamente en la cadena de entrada, lo que hace que '(a * a)' falle siempre. –