Skip to content

Commit 7f7ad87

Browse files
authored
Merge pull request #5033 from jix/liberty-fixes
liberty: More robust parsing
2 parents 08b3a9f + c555add commit 7f7ad87

File tree

5 files changed

+67
-10
lines changed

5 files changed

+67
-10
lines changed

passes/techmap/libparse.cc

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ bool LibertyInputStream::extend_buffer_once()
7575
buffer.resize(buf_end + chunk_size);
7676
}
7777

78-
size_t read_size = f.rdbuf()->sgetn(buffer.data() + buf_end, chunk_size);
78+
size_t read_size = f.rdbuf()->sgetn((char *)buffer.data() + buf_end, chunk_size);
7979
buf_end += read_size;
8080
if (read_size < chunk_size)
8181
eof = true;
@@ -436,6 +436,9 @@ void LibertyParser::report_unexpected_token(int tok)
436436
eReport += "'.";
437437
error(eReport);
438438
break;
439+
case EOF:
440+
error("Unexpected end of file");
441+
break;
439442
default:
440443
eReport = "Unexpected token: ";
441444
eReport += static_cast<char>(tok);
@@ -484,7 +487,7 @@ void LibertyParser::parse_vector_range(int tok)
484487
}
485488
}
486489

487-
LibertyAst *LibertyParser::parse()
490+
LibertyAst *LibertyParser::parse(bool top_level)
488491
{
489492
std::string str;
490493

@@ -498,7 +501,13 @@ LibertyAst *LibertyParser::parse()
498501
while ((tok == 'n') || (tok == ';'))
499502
tok = lexer(str);
500503

501-
if (tok == '}' || tok < 0)
504+
if (tok == EOF) {
505+
if (top_level)
506+
return NULL;
507+
report_unexpected_token(tok);
508+
}
509+
510+
if (tok == '}')
502511
return NULL;
503512

504513
if (tok != 'v') {
@@ -571,12 +580,18 @@ LibertyAst *LibertyParser::parse()
571580
}
572581

573582
if (tok == '{') {
583+
bool terminated = false;
574584
while (1) {
575-
LibertyAst *child = parse();
576-
if (child == NULL)
585+
LibertyAst *child = parse(false);
586+
if (child == NULL) {
587+
terminated = true;
577588
break;
589+
}
578590
ast->children.push_back(child);
579591
}
592+
if (!terminated) {
593+
report_unexpected_token(EOF);
594+
}
580595
break;
581596
}
582597

passes/techmap/libparse.h

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ namespace Yosys
9292

9393
class LibertyInputStream {
9494
std::istream &f;
95-
std::vector<char> buffer;
95+
std::vector<unsigned char> buffer;
9696
size_t buf_pos = 0;
9797
size_t buf_end = 0;
9898
bool eof = false;
@@ -107,7 +107,7 @@ namespace Yosys
107107
LibertyInputStream(std::istream &f) : f(f) {}
108108

109109
size_t buffered_size() { return buf_end - buf_pos; }
110-
const char *buffered_data() { return buffer.data() + buf_pos; }
110+
const unsigned char *buffered_data() { return buffer.data() + buf_pos; }
111111

112112
int get() {
113113
if (buf_pos == buf_end)
@@ -165,7 +165,7 @@ namespace Yosys
165165

166166
void report_unexpected_token(int tok);
167167
void parse_vector_range(int tok);
168-
LibertyAst *parse();
168+
LibertyAst *parse(bool top_level);
169169
void error() const;
170170
void error(const std::string &str) const;
171171

@@ -174,18 +174,29 @@ namespace Yosys
174174
const LibertyAst *ast = nullptr;
175175

176176
LibertyParser(std::istream &f) : f(f), line(1) {
177-
shared_ast.reset(parse());
177+
shared_ast.reset(parse(true));
178178
ast = shared_ast.get();
179+
if (!ast) {
180+
#ifdef FILTERLIB
181+
fprintf(stderr, "No entries found in liberty file.\n");
182+
exit(1);
183+
#else
184+
log_error("No entries found in liberty file.\n");
185+
#endif
186+
}
179187
}
180188

181189
#ifndef FILTERLIB
182190
LibertyParser(std::istream &f, const std::string &fname) : f(f), line(1) {
183191
shared_ast = LibertyAstCache::instance.cached_ast(fname);
184192
if (!shared_ast) {
185-
shared_ast.reset(parse());
193+
shared_ast.reset(parse(true));
186194
LibertyAstCache::instance.parsed_ast(fname, shared_ast);
187195
}
188196
ast = shared_ast.get();
197+
if (!ast) {
198+
log_error("No entries found in liberty file `%s'.\n", fname.c_str());
199+
}
189200
}
190201
#endif
191202
};

tests/liberty/non-ascii.lib

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// The parser used to choke on the copyright symbol even in comments
2+
// © ® ø Φ
3+
library(dummy) {
4+
cell(buffer) {
5+
area : 1 ;
6+
pin(A) {
7+
direction : input ;
8+
}
9+
pin(Y) {
10+
direction : output ;
11+
function : "A" ;
12+
}
13+
}
14+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
library(dummy) {
2+
cell(buffer) {
3+
area : 1 ;
4+
pin(A) {
5+
direction : input ;
6+
}
7+
pin(Y) {
8+
direction : output ;
9+
function : "A" ;
10+
}
11+
}
12+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module buffer (A, Y);
2+
input A;
3+
output Y;
4+
assign Y = A; // "A"
5+
endmodule

0 commit comments

Comments
 (0)