mirror of
https://github.com/YosysHQ/yosys
synced 2025-11-07 23:05:07 +00:00
libparse: quirk-compatibility for unquoted boolean expression strings
This commit is contained in:
parent
2d7a191b01
commit
66d8fc5c28
2 changed files with 61 additions and 22 deletions
|
|
@ -364,7 +364,7 @@ std::string LibertyExpression::str(int indent)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int LibertyParser::lexer(std::string &str)
|
int LibertyParser::lexer_inner(std::string &str)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
|
|
@ -390,11 +390,9 @@ int LibertyParser::lexer(std::string &str)
|
||||||
|
|
||||||
if (str == "+" || str == "-") {
|
if (str == "+" || str == "-") {
|
||||||
/* Single operator is not an identifier */
|
/* Single operator is not an identifier */
|
||||||
// fprintf(stderr, "LEX: char >>%s<<\n", str.c_str());
|
|
||||||
return str[0];
|
return str[0];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// fprintf(stderr, "LEX: identifier >>%s<<\n", str.c_str());
|
|
||||||
return 'v';
|
return 'v';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -402,24 +400,25 @@ int LibertyParser::lexer(std::string &str)
|
||||||
// if it wasn't an identifer, number of array range,
|
// if it wasn't an identifer, number of array range,
|
||||||
// maybe it's a string?
|
// maybe it's a string?
|
||||||
if (c == '"') {
|
if (c == '"') {
|
||||||
|
f.consume(1);
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
c = f.peek(i);
|
c = f.peek(i);
|
||||||
line += (c == '\n');
|
line += (c == '\n');
|
||||||
if (c != '"')
|
if (c != '"' && c != EOF)
|
||||||
i += 1;
|
i += 1;
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
str.clear();
|
str.clear();
|
||||||
#ifdef FILTERLIB
|
|
||||||
f.unget();
|
f.unget();
|
||||||
str.append(f.buffered_data(), f.buffered_data() + i + 2);
|
str.append(f.buffered_data(), f.buffered_data() + i + 1);
|
||||||
f.consume(i + 2);
|
// Usage in filterlib is expected to retain quotes
|
||||||
#else
|
// but yosys expects to get unquoted
|
||||||
str.append(f.buffered_data(), f.buffered_data() + i);
|
#ifdef FILTERLIB
|
||||||
f.consume(i + 1);
|
str = "\"" + str + "\"";
|
||||||
#endif
|
#endif
|
||||||
|
f.consume(i + 2);
|
||||||
return 'v';
|
return 'v';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -442,13 +441,12 @@ int LibertyParser::lexer(std::string &str)
|
||||||
return lexer(str);
|
return lexer(str);
|
||||||
}
|
}
|
||||||
f.unget();
|
f.unget();
|
||||||
// fprintf(stderr, "LEX: char >>/<<\n");
|
|
||||||
return '/'; // a single '/' charater.
|
return '/'; // a single '/' charater.
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for a backslash
|
// check for a backslash
|
||||||
if (c == '\\') {
|
if (c == '\\') {
|
||||||
c = f.get();
|
c = f.get();
|
||||||
if (c == '\r')
|
if (c == '\r')
|
||||||
c = f.get();
|
c = f.get();
|
||||||
if (c == '\n') {
|
if (c == '\n') {
|
||||||
|
|
@ -467,14 +465,22 @@ int LibertyParser::lexer(std::string &str)
|
||||||
|
|
||||||
// anything else, such as ';' will get passed
|
// anything else, such as ';' will get passed
|
||||||
// through as literal items.
|
// through as literal items.
|
||||||
|
|
||||||
// if (c >= 32 && c < 255)
|
|
||||||
// fprintf(stderr, "LEX: char >>%c<<\n", c);
|
|
||||||
// else
|
|
||||||
// fprintf(stderr, "LEX: char %d\n", c);
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int LibertyParser::lexer(std::string &str)
|
||||||
|
{
|
||||||
|
int ret = lexer_inner(str);
|
||||||
|
// if (ret >= 32 && ret < 255) {
|
||||||
|
// fprintf(stdout, "LEX: ret >>%c<<\n", ret);
|
||||||
|
// } else if (ret == 'v') {
|
||||||
|
// fprintf(stdout, "LEX: ret v str %s\n", str.c_str());
|
||||||
|
// } else {
|
||||||
|
// fprintf(stdout, "LEX: ret %d\n", ret);
|
||||||
|
// }
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
void LibertyParser::report_unexpected_token(int tok)
|
void LibertyParser::report_unexpected_token(int tok)
|
||||||
{
|
{
|
||||||
std::string eReport;
|
std::string eReport;
|
||||||
|
|
@ -545,6 +551,25 @@ void LibertyParser::parse_vector_range(int tok)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Consume into out_str any string-ish tokens, seperated with spaces
|
||||||
|
// to cope with abuse of the underdefined spec by real world PDKs
|
||||||
|
// enabled by proprietary implementations.
|
||||||
|
// Sorry.
|
||||||
|
int LibertyParser::consume_wrecked_str(int tok, std::string& out_str) {
|
||||||
|
std::string str = "";
|
||||||
|
while (tok != ';' && tok != EOF && tok != 'n') {
|
||||||
|
out_str += " ";
|
||||||
|
if (tok == 'v')
|
||||||
|
out_str += str;
|
||||||
|
else
|
||||||
|
out_str += tok;
|
||||||
|
tok = lexer(str);
|
||||||
|
}
|
||||||
|
if (tok == EOF)
|
||||||
|
error("wrecked string EOF");
|
||||||
|
return tok;
|
||||||
|
}
|
||||||
|
|
||||||
LibertyAst *LibertyParser::parse(bool top_level)
|
LibertyAst *LibertyParser::parse(bool top_level)
|
||||||
{
|
{
|
||||||
std::string str;
|
std::string str;
|
||||||
|
|
@ -591,17 +616,29 @@ LibertyAst *LibertyParser::parse(bool top_level)
|
||||||
if (tok == '[') {
|
if (tok == '[') {
|
||||||
parse_vector_range(tok);
|
parse_vector_range(tok);
|
||||||
tok = lexer(str);
|
tok = lexer(str);
|
||||||
|
} else {
|
||||||
|
// Hack for when an expression string is unquoted
|
||||||
|
// std::cout << "consume_wrecked_str from :\n";
|
||||||
|
// std::cout << " weh " << str << "\n";
|
||||||
|
tok = consume_wrecked_str(tok, ast->value);
|
||||||
}
|
}
|
||||||
|
} else if (tok == '(') {
|
||||||
|
// Hack for when an expression string is unquoted and starts with
|
||||||
|
// parentheses
|
||||||
|
// tok = '';
|
||||||
|
// ast->value = "(";
|
||||||
|
// std::cout << "consume_wrecked_str from (\n";
|
||||||
|
tok = consume_wrecked_str(tok, ast->value);
|
||||||
}
|
}
|
||||||
while (tok == '+' || tok == '-' || tok == '*' || tok == '/' || tok == '!') {
|
while (tok == '+' || tok == '-' || tok == '*' || tok == '/' || tok == '!') {
|
||||||
ast->value += tok;
|
ast->value += tok;
|
||||||
tok = lexer(str);
|
tok = lexer(str);
|
||||||
if (tok != 'v')
|
if (tok != 'v')
|
||||||
error();
|
error("one");
|
||||||
ast->value += str;
|
ast->value += str;
|
||||||
tok = lexer(str);
|
tok = lexer(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
// In a liberty file, all key : value pairs should end in ';'
|
// In a liberty file, all key : value pairs should end in ';'
|
||||||
// However, there are some liberty files in the wild that
|
// However, there are some liberty files in the wild that
|
||||||
// just have a newline. We'll be kind and accept a newline
|
// just have a newline. We'll be kind and accept a newline
|
||||||
|
|
@ -609,7 +646,7 @@ LibertyAst *LibertyParser::parse(bool top_level)
|
||||||
if ((tok == ';') || (tok == 'n'))
|
if ((tok == ';') || (tok == 'n'))
|
||||||
break;
|
break;
|
||||||
else
|
else
|
||||||
error();
|
error("two");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -621,11 +658,11 @@ LibertyAst *LibertyParser::parse(bool top_level)
|
||||||
continue;
|
continue;
|
||||||
if (tok == ')')
|
if (tok == ')')
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (tok == '[')
|
if (tok == '[')
|
||||||
{
|
{
|
||||||
parse_vector_range(tok);
|
parse_vector_range(tok);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (tok == 'n')
|
if (tok == 'n')
|
||||||
continue;
|
continue;
|
||||||
|
|
|
||||||
|
|
@ -170,10 +170,12 @@ namespace Yosys
|
||||||
'n': newline
|
'n': newline
|
||||||
anything else is a single character.
|
anything else is a single character.
|
||||||
*/
|
*/
|
||||||
|
int lexer_inner(std::string &str);
|
||||||
int lexer(std::string &str);
|
int lexer(std::string &str);
|
||||||
|
|
||||||
void report_unexpected_token(int tok);
|
void report_unexpected_token(int tok);
|
||||||
void parse_vector_range(int tok);
|
void parse_vector_range(int tok);
|
||||||
|
int consume_wrecked_str(int tok, std::string& out_str);
|
||||||
LibertyAst *parse(bool top_level);
|
LibertyAst *parse(bool top_level);
|
||||||
void error() const;
|
void error() const;
|
||||||
void error(const std::string &str) const;
|
void error(const std::string &str) const;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue