CIRCT 20.0.0git
Loading...
Searching...
No Matches
OMUtils.cpp
Go to the documentation of this file.
1//===- OMUtils.cpp - OM Utility Functions ---------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
11#include "llvm/ADT/SmallString.h"
12#include "llvm/ADT/SmallVector.h"
13#include "llvm/ADT/StringRef.h"
14
15using namespace circt;
16using namespace om;
17
18namespace {
19struct PathParser {
20 enum class TokenKind {
21 Space,
22 Tilde,
23 Bar,
24 Colon,
25 Greater,
26 Slash,
27 LBrace,
28 RBrace,
29 Period,
30 Id,
31 Eof
32 };
33
34 struct Token {
35 TokenKind kind;
36 StringRef spelling;
37 };
38
39 Token formToken(TokenKind kind, size_t n) {
40 auto s = spelling.take_front(n);
41 spelling = spelling.drop_front(n);
42 return {kind, s};
43 }
44
45 bool isIDChar(char c) {
46 return c != ' ' && c != '~' && c != '|' && c != ':' && c != '>' &&
47 c != '/' && c != '[' && c != ']' && c != '.';
48 }
49
50 Token parseToken() {
51 size_t pos = 0;
52 auto size = spelling.size();
53 if (0 == size)
54 return formToken(TokenKind::Eof, pos);
55 auto current = spelling[pos];
56 switch (current) {
57 case '~':
58 return formToken(TokenKind::Tilde, pos + 1);
59 case '|':
60 return formToken(TokenKind::Bar, pos + 1);
61 case ':':
62 return formToken(TokenKind::Colon, pos + 1);
63 case '>':
64 return formToken(TokenKind::Greater, pos + 1);
65 case '/':
66 return formToken(TokenKind::Slash, pos + 1);
67 case '[':
68 return formToken(TokenKind::LBrace, pos + 1);
69 case ']':
70 return formToken(TokenKind::RBrace, pos + 1);
71 case '.':
72 return formToken(TokenKind::Period, pos + 1);
73 default:
74 break;
75 }
76
77 // Parsing a token.
78 while (pos != size && isIDChar(spelling[pos]))
79 ++pos;
80 return formToken(TokenKind::Id, pos);
81 }
82
83 ParseResult parseToken(TokenKind kind, StringRef &result) {
84 auto save = spelling;
85 auto token = parseToken();
86 if (token.kind != kind)
87 return spelling = save, failure();
88 result = token.spelling;
89 return success();
90 }
91
92 ParseResult parseToken(TokenKind kind) {
93 StringRef ignore;
94 return parseToken(kind, ignore);
95 }
96
97 /// basepath ::= eof | id '/' id (':' id '/' id)* eof
98 ParseResult parseBasePath(PathAttr &pathAttr) {
99 if (succeeded(parseToken(TokenKind::Eof)))
100 return success();
101 SmallVector<PathElement> path;
102 while (true) {
103 StringRef module;
104 StringRef instance;
105 if (parseToken(TokenKind::Id, module) || parseToken(TokenKind::Slash) ||
106 parseToken(TokenKind::Id, instance))
107 return failure();
108 path.emplace_back(StringAttr::get(context, module),
109 StringAttr::get(context, instance));
110 if (parseToken(TokenKind::Colon))
111 break;
112 }
113 pathAttr = PathAttr::get(context, path);
114 if (parseToken(TokenKind::Eof))
115 return failure();
116 return success();
117 }
118
119 /// path ::= id ('/' id ':' path | ('>' id ('[' id ']' | '.' id)* )?) eof
120 ParseResult parsePath(PathAttr &pathAttr, StringAttr &moduleAttr,
121 StringAttr &refAttr, StringAttr &fieldAttr) {
122 SmallVector<PathElement> path;
123 StringRef module;
124 while (true) {
125 if (parseToken(TokenKind::Id, module))
126 return failure();
127 if (parseToken(TokenKind::Slash))
128 break;
129 StringRef instance;
130 if (parseToken(TokenKind::Id, instance) || parseToken(TokenKind::Colon))
131 return failure();
132 path.emplace_back(StringAttr::get(context, module),
133 StringAttr::get(context, instance));
134 }
135 pathAttr = PathAttr::get(context, path);
136 moduleAttr = StringAttr::get(context, module);
137 if (succeeded(parseToken(TokenKind::Greater))) {
138 StringRef ref;
139 if (parseToken(TokenKind::Id, ref))
140 return failure();
141 refAttr = StringAttr::get(context, ref);
142
143 SmallString<64> field;
144 while (true) {
145 if (succeeded(parseToken(TokenKind::LBrace))) {
146 StringRef id;
147 if (parseToken(TokenKind::Id, id) || parseToken(TokenKind::RBrace))
148 return failure();
149 field += '[';
150 field += id;
151 field += ']';
152 } else if (succeeded(parseToken(TokenKind::Period))) {
153 StringRef id;
154 if (parseToken(TokenKind::Id, id))
155 return failure();
156 field += '.';
157 field += id;
158 } else {
159 break;
160 }
161 }
162 fieldAttr = StringAttr::get(context, field);
163 } else {
164 refAttr = StringAttr::get(context, "");
165 fieldAttr = StringAttr::get(context, "");
166 }
167 if (parseToken(TokenKind::Eof))
168 return failure();
169 return success();
170 }
171
172 MLIRContext *context;
173 StringRef spelling;
174};
175} // namespace
176
177ParseResult circt::om::parseBasePath(MLIRContext *context, StringRef spelling,
178 PathAttr &path) {
179 return PathParser{context, spelling}.parseBasePath(path);
180}
181
182ParseResult circt::om::parsePath(MLIRContext *context, StringRef spelling,
183 PathAttr &path, StringAttr &module,
184 StringAttr &ref, StringAttr &field) {
185 return PathParser{context, spelling}.parsePath(path, module, ref, field);
186}
ParseResult parsePath(MLIRContext *context, StringRef spelling, PathAttr &path, StringAttr &module, StringAttr &ref, StringAttr &field)
Parse a target string in to a path.
Definition OMUtils.cpp:182
ParseResult parseBasePath(MLIRContext *context, StringRef spelling, PathAttr &path)
Parse a target string of the form "Foo/bar:Bar/baz" in to a base path.
Definition OMUtils.cpp:177
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Definition om.py:1