github.com/vcilabs/webrpc@v0.5.2-0.20201116131534-162e27b1b33b/schema/ridl/import_parser.go (about) 1 package ridl 2 3 func parserStateImportMembers(p *parser, in *ImportNode) parserState { 4 5 tok := p.cursor() 6 7 switch tok.tt { 8 case tokenNewLine, tokenWhitespace: 9 // ignore whitespace 10 p.next() 11 12 case tokenDash: 13 14 // - <value> [<# comment>][EOL] 15 if _, err := p.match(tokenDash, tokenWhitespace); err != nil { 16 return p.stateError(err) 17 } 18 19 member, err := p.expectLiteralValue() 20 if err != nil { 21 return p.stateError(err) 22 } 23 24 in.members = append(in.members, newTokenNode(member)) 25 26 case tokenHash: 27 p.continueUntilEOL() 28 29 default: 30 p.emit(in) 31 32 return parserDefaultState 33 34 } 35 36 return parserStateImportMembers(p, in) 37 } 38 39 func parserStateImportValue(p *parser) parserState { 40 tok := p.cursor() 41 42 switch tok.tt { 43 44 case tokenNewLine, tokenWhitespace: 45 // ignore whitespace 46 p.next() 47 48 case tokenDash: 49 50 // - <value> [<# comment>][EOL] 51 if _, err := p.match(tokenDash, tokenWhitespace); err != nil { 52 return p.stateError(err) 53 } 54 55 path, err := p.expectPath() 56 if err != nil { 57 return p.stateError(err) 58 } 59 60 p.emit(&ImportNode{ 61 path: newTokenNode(path), 62 members: []*TokenNode{}, 63 }) 64 65 return parserStateImportValue 66 67 case tokenHash: 68 p.continueUntilEOL() 69 70 default: 71 return parserDefaultState 72 73 } 74 75 return parserStateImportValue 76 } 77 78 func parserStateImport(p *parser) parserState { 79 80 { 81 // import[<space>][<# comment>]<EOL> 82 matches, err := p.match(tokenWord, tokenEOL) 83 if err == nil { 84 if err = expectWord(matches[0], wordImport); err != nil { 85 return p.stateError(err) 86 } 87 return parserStateImportValue 88 } 89 } 90 91 { 92 // import<space><import path><# comment>]<EOL> 93 _, err := p.match(tokenWhitespace) 94 if err != nil { 95 return p.stateError(err) 96 } 97 98 path, err := p.expectPath() 99 if err != nil { 100 return p.stateError(err) 101 } 102 103 importNode := &ImportNode{ 104 path: newTokenNode(path), 105 } 106 107 return parserStateImportMembers(p, importNode) 108 } 109 110 return parserDefaultState 111 112 } 113 114 func (p *parser) expectPath() (*token, error) { 115 tokens := []*token{} 116 117 loop: 118 for { 119 // TODO: should we allow enclosing literal values with quotes? 120 tok := p.cursor() 121 122 switch tok.tt { 123 124 // literal value enclosed by string 125 case tokenQuote: 126 var err error 127 tok, err = p.expectStringValue() 128 if err != nil { 129 return nil, err 130 } 131 return tok, nil 132 133 case tokenWord, tokenDot, tokenSlash: 134 tokens = append(tokens, tok) 135 p.next() 136 137 default: 138 break loop 139 } 140 } 141 142 return composedValue(tokens) 143 }