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