3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-04-24 01:25:33 +00:00

Merge pull request #4976 from Logikable/main

Support array ranges for identifiers in the Liberty parser.
This commit is contained in:
Emil J 2025-04-09 22:49:52 +02:00 committed by GitHub
commit a5e8f52ce5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 156 additions and 144 deletions

View file

@ -417,6 +417,73 @@ int LibertyParser::lexer(std::string &str)
return c;
}
void LibertyParser::report_unexpected_token(int tok)
{
std::string eReport;
switch(tok)
{
case 'n':
error("Unexpected newline.");
break;
case '[':
case ']':
case '}':
case '{':
case '\"':
case ':':
eReport = "Unexpected '";
eReport += static_cast<char>(tok);
eReport += "'.";
error(eReport);
break;
default:
eReport = "Unexpected token: ";
eReport += static_cast<char>(tok);
error(eReport);
}
}
// FIXME: the AST needs to be extended to store
// these vector ranges.
void LibertyParser::parse_vector_range(int tok)
{
// parse vector range [A] or [A:B]
std::string arg;
tok = lexer(arg);
if (tok != 'v')
{
// expected a vector array index
error("Expected a number.");
}
else
{
// fixme: check for number A
}
tok = lexer(arg);
// optionally check for : in case of [A:B]
// if it isn't we just expect ']'
// as we have [A]
if (tok == ':')
{
tok = lexer(arg);
if (tok != 'v')
{
// expected a vector array index
error("Expected a number.");
}
else
{
// fixme: check for number B
tok = lexer(arg);
}
}
// expect a closing bracket of array range
if (tok != ']')
{
error("Expected ']' on array range.");
}
}
LibertyAst *LibertyParser::parse()
{
std::string str;
@ -435,26 +502,7 @@ LibertyAst *LibertyParser::parse()
return NULL;
if (tok != 'v') {
std::string eReport;
switch(tok)
{
case 'n':
error("Unexpected newline.");
break;
case '[':
case ']':
case '}':
case '{':
case '\"':
case ':':
eReport = "Unexpected '";
eReport += static_cast<char>(tok);
eReport += "'.";
error(eReport);
break;
default:
error();
}
report_unexpected_token(tok);
}
LibertyAst *ast = new LibertyAst;
@ -472,7 +520,11 @@ LibertyAst *LibertyParser::parse()
if (tok == ':' && ast->value.empty()) {
tok = lexer(ast->value);
if (tok == 'v') {
tok = lexer(str);
tok = lexer(str);
if (tok == '[') {
parse_vector_range(tok);
tok = lexer(str);
}
}
while (tok == '+' || tok == '-' || tok == '*' || tok == '/' || tok == '!') {
ast->value += tok;
@ -503,67 +555,15 @@ LibertyAst *LibertyParser::parse()
if (tok == ')')
break;
// FIXME: the AST needs to be extended to store
// these vector ranges.
if (tok == '[')
{
// parse vector range [A] or [A:B]
std::string arg;
tok = lexer(arg);
if (tok != 'v')
{
// expected a vector array index
error("Expected a number.");
}
else
{
// fixme: check for number A
}
tok = lexer(arg);
// optionally check for : in case of [A:B]
// if it isn't we just expect ']'
// as we have [A]
if (tok == ':')
{
tok = lexer(arg);
if (tok != 'v')
{
// expected a vector array index
error("Expected a number.");
}
else
{
// fixme: check for number B
tok = lexer(arg);
}
}
// expect a closing bracket of array range
if (tok != ']')
{
error("Expected ']' on array range.");
}
parse_vector_range(tok);
continue;
}
if (tok == 'n')
continue;
if (tok != 'v') {
std::string eReport;
switch(tok)
{
case 'n':
continue;
case '[':
case ']':
case '}':
case '{':
case '\"':
case ':':
eReport = "Unexpected '";
eReport += static_cast<char>(tok);
eReport += "'.";
error(eReport);
break;
default:
error();
}
report_unexpected_token(tok);
}
ast->args.push_back(arg);
}
@ -580,7 +580,7 @@ LibertyAst *LibertyParser::parse()
break;
}
error();
report_unexpected_token(tok);
}
return ast;

View file

@ -163,6 +163,8 @@ namespace Yosys
*/
int lexer(std::string &str);
void report_unexpected_token(int tok);
void parse_vector_range(int tok);
LibertyAst *parse();
void error() const;
void error(const std::string &str) const;