1 | // |
2 | // AttributesParser.cpp |
3 | // |
4 | // Library: CppParser |
5 | // Package: Attributes |
6 | // Module: AttributesParser |
7 | // |
8 | // Copyright (c) 2006, Applied Informatics Software Engineering GmbH. |
9 | // and Contributors. |
10 | // |
11 | // SPDX-License-Identifier: BSL-1.0 |
12 | // |
13 | |
14 | |
15 | #include "Poco/CppParser/AttributesParser.h" |
16 | #include "Poco/CppParser/CppToken.h" |
17 | #include "Poco/Exception.h" |
18 | |
19 | |
20 | using Poco::Token; |
21 | using Poco::SyntaxException; |
22 | |
23 | |
24 | namespace Poco { |
25 | namespace CppParser { |
26 | |
27 | |
28 | AttributesParser::AttributesParser(Attributes& attrs, std::istream& istr): |
29 | _attrs(attrs), |
30 | _tokenizer(istr) |
31 | { |
32 | } |
33 | |
34 | |
35 | AttributesParser::~AttributesParser() |
36 | { |
37 | } |
38 | |
39 | |
40 | void AttributesParser::parse() |
41 | { |
42 | const Token* pNext = next(); |
43 | if (!isEOF(pNext)) |
44 | { |
45 | pNext = parseAttributes(pNext); |
46 | } |
47 | if (!isEOF(pNext)) |
48 | throw Poco::SyntaxException("extra tokens found in attribute declaration" ); |
49 | } |
50 | |
51 | |
52 | const Token* AttributesParser::parseAttributes(const Token* pNext) |
53 | { |
54 | pNext = parseAttribute(pNext); |
55 | while (isOperator(pNext, OperatorToken::OP_COMMA) || isIdentifier(pNext)) |
56 | { |
57 | if (!isIdentifier(pNext)) pNext = next(); |
58 | pNext = parseAttribute(pNext); |
59 | } |
60 | return pNext; |
61 | } |
62 | |
63 | |
64 | const Token* AttributesParser::parseAttribute(const Token* pNext) |
65 | { |
66 | std::string id; |
67 | std::string value; |
68 | pNext = parseIdentifier(pNext, id); |
69 | if (isOperator(pNext, OperatorToken::OP_ASSIGN)) |
70 | { |
71 | pNext = next(); |
72 | if (isOperator(pNext, OperatorToken::OP_OPENBRACE)) |
73 | { |
74 | pNext = parseComplexAttribute(pNext, id); |
75 | } |
76 | else if (isIdentifier(pNext) || isLiteral(pNext)) |
77 | { |
78 | value = pNext->asString(); |
79 | pNext = next(); |
80 | } |
81 | else throw SyntaxException("bad attribute declaration" ); |
82 | } |
83 | setAttribute(id, value); |
84 | return pNext; |
85 | } |
86 | |
87 | |
88 | const Token* AttributesParser::parseComplexAttribute(const Token* pNext, const std::string& id) |
89 | { |
90 | poco_assert_dbg (isOperator(pNext, OperatorToken::OP_OPENBRACE)); |
91 | |
92 | pNext = next(); |
93 | std::string oldId(_id); |
94 | if (!_id.empty()) |
95 | { |
96 | _id.append("." ); |
97 | _id.append(id); |
98 | } |
99 | else _id = id; |
100 | pNext = parseAttributes(pNext); |
101 | _id = oldId; |
102 | if (isOperator(pNext, OperatorToken::OP_CLOSBRACE)) |
103 | pNext = next(); |
104 | else |
105 | throw SyntaxException("bad attribute declaration" ); |
106 | |
107 | return pNext; |
108 | } |
109 | |
110 | |
111 | const Token* AttributesParser::(const Token* pNext, std::string& id) |
112 | { |
113 | if (isIdentifier(pNext)) |
114 | { |
115 | id = pNext->asString(); |
116 | pNext = next(); |
117 | while (isOperator(pNext, OperatorToken::OP_PERIOD)) |
118 | { |
119 | id.append("." ); |
120 | pNext = next(); |
121 | if (isIdentifier(pNext)) |
122 | { |
123 | id.append(pNext->asString()); |
124 | pNext = next(); |
125 | } |
126 | else throw SyntaxException("identifier expected" ); |
127 | } |
128 | return pNext; |
129 | } |
130 | else throw SyntaxException("identifier expected" ); |
131 | } |
132 | |
133 | |
134 | void AttributesParser::setAttribute(const std::string& name, const std::string& value) |
135 | { |
136 | std::string n; |
137 | if (!_id.empty()) |
138 | { |
139 | n.append(_id); |
140 | n.append("." ); |
141 | } |
142 | n.append(name); |
143 | _attrs.set(n, value); |
144 | } |
145 | |
146 | |
147 | } } // namespace Poco::CppParser |
148 | |