Home | History | Annotate | Download | only in declarations
      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 
     39     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