Supponiamo che sto scrivendo un parser SQL rudimentale in Scala. Ho il seguente:corrispondenza non avida in 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
}
Quando si cerca di abbinare selectstatement contro SELECT foo FROM bar
, come faccio a impedire che il selectclause dal inghiottendo l'intera frase a causa della rep(token)
in ~ tokens
?
In altre parole, come si specifica la corrispondenza non avida in Scala?
Per chiarire, sono pienamente consapevole che posso utilizzare la sintassi non greedy standard (*?) O (+?) All'interno del pattern String stesso, ma mi chiedevo se c'è un modo per specificarlo a un livello superiore all'interno di token di sicurezza. Ad esempio, se avessi definita del token in questo modo:
def token: Parser[Any] = stringliteral | numericliteral | columnname
Allora come posso specificare corrispondenza non avido per il rappresentante (token) all'interno gettoni def?
Sembra che abbiamo a che fare [con funzione di PEG] (https://en.wikipedia.org/wiki/Parsing_expression_grammar#Operational_interpretation_of_parsing_expressions) qui: considerando che matchers espressioni regolari possono iniziare abbinando avidamente, ma sarà poi marcia indietro e prova le corrispondenze più brevi se falliscono e CFG prova ogni possibilità, gli operatori '*', '+', e '? PEG si comportano sempre avidamente, consumano il maggior numero possibile di input e non tornano indietro: Expression' a * 'consumerà sempre come molti a come sono disponibili consecutivamente nella stringa di input, causando sempre il '(a * a)'. –