mirror of
https://github.com/YosysHQ/yosys
synced 2025-04-20 07:36:39 +00:00
Merge pull request #5033 from jix/liberty-fixes
liberty: More robust parsing
This commit is contained in:
commit
7f7ad87b7b
|
@ -75,7 +75,7 @@ bool LibertyInputStream::extend_buffer_once()
|
|||
buffer.resize(buf_end + chunk_size);
|
||||
}
|
||||
|
||||
size_t read_size = f.rdbuf()->sgetn(buffer.data() + buf_end, chunk_size);
|
||||
size_t read_size = f.rdbuf()->sgetn((char *)buffer.data() + buf_end, chunk_size);
|
||||
buf_end += read_size;
|
||||
if (read_size < chunk_size)
|
||||
eof = true;
|
||||
|
@ -436,6 +436,9 @@ void LibertyParser::report_unexpected_token(int tok)
|
|||
eReport += "'.";
|
||||
error(eReport);
|
||||
break;
|
||||
case EOF:
|
||||
error("Unexpected end of file");
|
||||
break;
|
||||
default:
|
||||
eReport = "Unexpected token: ";
|
||||
eReport += static_cast<char>(tok);
|
||||
|
@ -484,7 +487,7 @@ void LibertyParser::parse_vector_range(int tok)
|
|||
}
|
||||
}
|
||||
|
||||
LibertyAst *LibertyParser::parse()
|
||||
LibertyAst *LibertyParser::parse(bool top_level)
|
||||
{
|
||||
std::string str;
|
||||
|
||||
|
@ -498,7 +501,13 @@ LibertyAst *LibertyParser::parse()
|
|||
while ((tok == 'n') || (tok == ';'))
|
||||
tok = lexer(str);
|
||||
|
||||
if (tok == '}' || tok < 0)
|
||||
if (tok == EOF) {
|
||||
if (top_level)
|
||||
return NULL;
|
||||
report_unexpected_token(tok);
|
||||
}
|
||||
|
||||
if (tok == '}')
|
||||
return NULL;
|
||||
|
||||
if (tok != 'v') {
|
||||
|
@ -571,12 +580,18 @@ LibertyAst *LibertyParser::parse()
|
|||
}
|
||||
|
||||
if (tok == '{') {
|
||||
bool terminated = false;
|
||||
while (1) {
|
||||
LibertyAst *child = parse();
|
||||
if (child == NULL)
|
||||
LibertyAst *child = parse(false);
|
||||
if (child == NULL) {
|
||||
terminated = true;
|
||||
break;
|
||||
}
|
||||
ast->children.push_back(child);
|
||||
}
|
||||
if (!terminated) {
|
||||
report_unexpected_token(EOF);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -92,7 +92,7 @@ namespace Yosys
|
|||
|
||||
class LibertyInputStream {
|
||||
std::istream &f;
|
||||
std::vector<char> buffer;
|
||||
std::vector<unsigned char> buffer;
|
||||
size_t buf_pos = 0;
|
||||
size_t buf_end = 0;
|
||||
bool eof = false;
|
||||
|
@ -107,7 +107,7 @@ namespace Yosys
|
|||
LibertyInputStream(std::istream &f) : f(f) {}
|
||||
|
||||
size_t buffered_size() { return buf_end - buf_pos; }
|
||||
const char *buffered_data() { return buffer.data() + buf_pos; }
|
||||
const unsigned char *buffered_data() { return buffer.data() + buf_pos; }
|
||||
|
||||
int get() {
|
||||
if (buf_pos == buf_end)
|
||||
|
@ -165,7 +165,7 @@ namespace Yosys
|
|||
|
||||
void report_unexpected_token(int tok);
|
||||
void parse_vector_range(int tok);
|
||||
LibertyAst *parse();
|
||||
LibertyAst *parse(bool top_level);
|
||||
void error() const;
|
||||
void error(const std::string &str) const;
|
||||
|
||||
|
@ -174,18 +174,29 @@ namespace Yosys
|
|||
const LibertyAst *ast = nullptr;
|
||||
|
||||
LibertyParser(std::istream &f) : f(f), line(1) {
|
||||
shared_ast.reset(parse());
|
||||
shared_ast.reset(parse(true));
|
||||
ast = shared_ast.get();
|
||||
if (!ast) {
|
||||
#ifdef FILTERLIB
|
||||
fprintf(stderr, "No entries found in liberty file.\n");
|
||||
exit(1);
|
||||
#else
|
||||
log_error("No entries found in liberty file.\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef FILTERLIB
|
||||
LibertyParser(std::istream &f, const std::string &fname) : f(f), line(1) {
|
||||
shared_ast = LibertyAstCache::instance.cached_ast(fname);
|
||||
if (!shared_ast) {
|
||||
shared_ast.reset(parse());
|
||||
shared_ast.reset(parse(true));
|
||||
LibertyAstCache::instance.parsed_ast(fname, shared_ast);
|
||||
}
|
||||
ast = shared_ast.get();
|
||||
if (!ast) {
|
||||
log_error("No entries found in liberty file `%s'.\n", fname.c_str());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
|
14
tests/liberty/non-ascii.lib
Normal file
14
tests/liberty/non-ascii.lib
Normal file
|
@ -0,0 +1,14 @@
|
|||
// The parser used to choke on the copyright symbol even in comments
|
||||
// © ® ø Φ
|
||||
library(dummy) {
|
||||
cell(buffer) {
|
||||
area : 1 ;
|
||||
pin(A) {
|
||||
direction : input ;
|
||||
}
|
||||
pin(Y) {
|
||||
direction : output ;
|
||||
function : "A" ;
|
||||
}
|
||||
}
|
||||
}
|
12
tests/liberty/non-ascii.lib.filtered.ok
Normal file
12
tests/liberty/non-ascii.lib.filtered.ok
Normal file
|
@ -0,0 +1,12 @@
|
|||
library(dummy) {
|
||||
cell(buffer) {
|
||||
area : 1 ;
|
||||
pin(A) {
|
||||
direction : input ;
|
||||
}
|
||||
pin(Y) {
|
||||
direction : output ;
|
||||
function : "A" ;
|
||||
}
|
||||
}
|
||||
}
|
5
tests/liberty/non-ascii.lib.verilogsim.ok
Normal file
5
tests/liberty/non-ascii.lib.verilogsim.ok
Normal file
|
@ -0,0 +1,5 @@
|
|||
module buffer (A, Y);
|
||||
input A;
|
||||
output Y;
|
||||
assign Y = A; // "A"
|
||||
endmodule
|
Loading…
Reference in a new issue