• 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 parser.elements.DocParser
23 import writer.tokenValues
24 import java.text.ParseException
25 
26 /**
27  * Used for Structs and Unions
28  */
29 class CompoundDeclarationParser(iter: ListIterator<Token>, var shouldResetIterator: Boolean = false) : AbstractDeclarationParser(iter) {
30     lateinit var type: TokenGrammar
31     lateinit override var name: String
32     var members = mutableListOf<IMemberDeclaration>() //defined below
33 
34     init {
35         parseTokens(scanTokens(iter))
36         if (shouldResetIterator) resetIterator(iter)
37     }
38 
parseTokensnull39     override fun parseTokens(tokens: List<Token>) {
40         val iter = tokens.listIterator()
41         var token = iter.next()
42         assert(token.identifier == TokenGrammar.STRUCT || token.identifier == TokenGrammar.UNION)
43         assert(tokens.last().identifier == TokenGrammar.SEMICOLON)
44 
45         //type - struct or union
46         this.type = token.identifier
47 
48         //name
49         token = iter.next()
50         if (token.category != TokenCategory.Word)
51             throw ParseException("Invalid struct name: ${tokenValues(tokens)}", this.indexStart)
52         this.name = token.value
53 
54         //parse each semicolon-delimited statement
55         scanDelimitedList(iter,
56                 delimiter = TokenGrammar.SEMICOLON,
57                 openDelimiter = TokenGrammar.BRACE_OPEN,
58                 closeDelimiter = TokenGrammar.BRACE_CLOSE)
59                 .forEach {
60                     var docParser: DocParser? = null
61                     var statementTokens = it.toMutableList()
62                     if (statementTokens.isEmpty())
63                         throw ParseException("Invalid statement in: ${tokenValues(tokens)}", this.indexStart)
64 
65                     //If doc, extract doc tokens and parse, and remove from statement tokens
66                     if (statementTokens.first().identifier == TokenGrammar.DOC_START) {
67                         val idx = statementTokens.indexOfFirst { it.identifier == TokenGrammar.DOC_END }
68                         if (idx == -1) throw ParseException("Unable to find doc_end", this.indexStart)
69                         val docTokens = statementTokens.subList(0, idx+1)
70                         docParser = DocParser(docTokens.listIterator())
71                         statementTokens = statementTokens.subList(idx+1, statementTokens.size)
72                     }
73 
74                     if (statementTokens.isEmpty())
75                         throw ParseException("Invalid statement in: ${tokenValues(tokens)}", this.indexStart)
76 
77                     when(statementTokens.first().identifier) {
78                         TokenGrammar.STRUCT, TokenGrammar.UNION -> {
79                             assert(statementTokens.first().category == TokenCategory.TypeDef)
80                             this.members.add(CompoundMemberDeclaration(
81                                     typeDef = statementTokens.first().identifier,
82                                     type = statementTokens.get(1).value,
83                                     name = statementTokens.last().value,
84                                     docParser = docParser,
85                                     tokens = statementTokens.subList(2, statementTokens.size-1)
86                             ))
87                         }
88                         TokenGrammar.ENUM -> {
89                             assert(statementTokens.size > 1)
90                             this.members.add(MemberDeclaration(
91                                     type = statementTokens.first().value,
92                                     name = statementTokens.get(1).value,
93                                     docParser = docParser,
94                                     tokens = statementTokens
95                             ))
96                         }
97                         else -> {
98                             this.members.add(MemberDeclaration(
99                                     type = statementTokens.first().value,
100                                     name = statementTokens.last().value,
101                                     docParser = docParser,
102                                     tokens = statementTokens
103                             ))
104                         }
105                     }
106                 }
107     }
108 }
109 
110 interface IMemberDeclaration {
111     val type: String
112     val name: String
113     val docParser: DocParser?
114     val tokens: List<Token> //TODO: doesn't seem needed
115 }
116 
117 class MemberDeclaration(override val type: String,
118                         override val name: String,
119                         override val docParser: DocParser?,
120                         override val tokens: List<Token>) : IMemberDeclaration
121 
122 class CompoundMemberDeclaration(override val type: String,
123                                 override val name: String,
124                                 override val docParser: DocParser?,
125                                 override val tokens: List<Token>,
126                                 val typeDef: TokenGrammar) : IMemberDeclaration
127