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  }