// lexInside lexes the content inside a query block. func lexInside(l *lex.Lexer) lex.StateFn { for { switch r := l.Next(); { case r == period: if l.Next() == period && l.Next() == period { return lexFragmentSpread } // We do not expect a period at all. If you do, you may want to // backup the two extra periods we try to read. return l.Errorf("Unrecognized character in lexInside: %#U", r) case r == rightCurl: l.Depth-- l.Emit(itemRightCurl) if l.Depth == 0 { return lexText } case r == leftCurl: l.Depth++ l.Emit(itemLeftCurl) case r == lex.EOF: return l.Errorf("Unclosed action") case isSpace(r) || isEndOfLine(r) || r == comma: l.Ignore() case isNameBegin(r): return lexName case r == '#': l.Backup() return lexComment case r == leftRound: l.Emit(itemLeftRound) l.AcceptRun(isSpace) l.Ignore() k := l.Next() if k == '_' || l.Depth != 1 || l.Mode == fragmentMode { l.Backup() l.Emit(itemArgument) return lexArgInside } // This is a generator function. l.Backup() l.Emit(itemGenerator) l.FilterDepth++ return lexFilterInside case r == ':': return lexAlias case r == '@': return lexDirective default: return l.Errorf("Unrecognized character in lexInside: %#U", r) } } }
func lexAlias(l *lex.Lexer) lex.StateFn { l.AcceptRun(isSpace) l.Ignore() // Any spaces encountered. for { r := l.Next() if isNameSuffix(r) { continue } l.Backup() l.Emit(itemAlias) break } return lexInside }
func lexLanguage(l *lex.Lexer) lex.StateFn { r := l.Next() if r != '@' { return l.Errorf("Expected @ prefix for lexLanguage") } l.Ignore() r = l.Next() if !isLangTagPrefix(r) { return l.Errorf("Invalid language tag prefix: %v", r) } l.AcceptRun(isLangTag) l.Emit(itemLanguage) return lexText }
// lexArgVal lexes and emits the value part of an argument. func lexArgVal(l *lex.Lexer) lex.StateFn { l.AcceptRun(isSpace) l.Ignore() // Any spaces encountered. for { r := l.Next() if isSpace(r) || isEndOfLine(r) || r == rightRound || r == comma { l.Backup() l.Emit(itemArgVal) return lexArgInside } if r == lex.EOF { return l.Errorf("Reached lex.EOF while reading var value: %v", l.Input[l.Start:l.Pos]) } } }
func lexArgVal(l *lex.Lexer) lex.StateFn { l.AcceptRun(isSpace) l.Ignore() // Any spaces encountered. for { r := l.Next() if isSpace(r) || isEndOfLine(r) || r == ')' || r == ',' { l.Backup() l.Emit(itemArgVal) return lexArgInside } if r == lex.EOF { return l.Errorf("Reached lex.EOF while reading var value: %v", l.Input[l.Start:l.Pos]) } } glog.Fatal("This shouldn't be reached.") return nil }
// lexFilterFuncInside expects input to look like ("...", "..."). func lexFilterFuncInside(l *lex.Lexer) lex.StateFn { l.AcceptRun(isSpace) l.Ignore() // Any spaces encountered. for { r := l.Next() if isSpace(r) || r == ',' { l.Ignore() } else if r == leftRound { l.Emit(itemLeftRound) } else if r == rightRound { l.Emit(itemRightRound) return lexFilterInside } else if isEndLiteral(r) { l.Ignore() l.AcceptUntil(isEndLiteral) // This call will backup the ending ". l.Emit(itemFilterFuncArg) l.Next() // Consume " and ignore it. l.Ignore() } else { return l.Errorf("Expected quotation mark in lexFilterFuncArgs") } } }