• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package parser.elements.declarations
18 
19 import lexer.Token
20 import lexer.TokenCategory
21 import lexer.TokenGrammar
22 import writer.tokenValues
23 import java.text.ParseException
24 
25 data class ArgEntry(val type: String, val name: String)
26 
27 class MethodDeclarationParser(iter: ListIterator<Token>, var shouldResetIterator: Boolean = false) : AbstractDeclarationParser(iter) {
28     lateinit override var name: String
29 
30     var prefix: String? = null
31     var params = mutableListOf<ArgEntry>()
32     var returns = mutableListOf<ArgEntry>()
33 
34     init {
35         parseTokens(scanTokens(iter))
36         if (shouldResetIterator) resetIterator(iter)
37     }
38 
39     // [prefix] <name> ( [typedef] [name], ...) [generates] ( [typedef], [name], ...);
parseTokensnull40     override fun parseTokens(tokens: List<Token>) {
41         assert(tokens.last().identifier == TokenGrammar.SEMICOLON)
42         val iter = tokens.listIterator()
43         var token = iter.next()
44 
45         //grab prefix (typedef or keyword), if there
46         if (token.category == TokenCategory.TypeDef || token.category == TokenCategory.Keyword) {
47             this.prefix = token.value
48             token = iter.next()
49         }
50 
51         //name
52         if (token.category != TokenCategory.Word) {
53             throw ParseException("Invalid declarationParser name: '${token.value}'\nBad Tokens: ${tokenValues(tokens)}",
54                     this.indexStart)
55         }
56         this.name = token.value
57 
58         assert(iter.hasNext())
59         token = iter.next()
60 
61         //parse arg list
62         if (token.identifier == TokenGrammar.PAREN_OPEN) {
63             addArgs(iter, this.params)
64             assert(iter.hasNext())
65             token = iter.next()
66         }
67 
68         //parse return list
69         if (token.identifier == TokenGrammar.GENERATES) {
70             addArgs(iter, this.returns)
71             assert(iter.hasNext())
72             token = iter.next()
73         }
74 
75         assert(token.identifier == TokenGrammar.SEMICOLON)
76     }
77 
78     /**
79      * Arguments are provided in the form: (type1 name1, type2 name2, ...)
80      */
addArgsnull81     private fun addArgs(iter: ListIterator<Token>, list: MutableList<ArgEntry>) {
82         val argLists = this.scanDelimitedList(iter) //return list of list<token>
83         for (argList in argLists) {
84             list.add(formatArgEntry(argList)) //use tokens to create ArgEntry
85         }
86     }
87 
formatArgEntrynull88     private fun formatArgEntry(paramTokens: List<Token>): ArgEntry {
89         val type = paramTokens.takeWhile { it != paramTokens.last() } //but-last
90                 .map { it.value }
91                 .joinToString("")
92         val name = paramTokens.last().value
93         return ArgEntry(type, name)
94     }
95 }