Added Verilog lexer and parser support for real values
authorClifford Wolf <clifford@clifford.at>
Fri, 13 Jun 2014 09:29:23 +0000 (11:29 +0200)
committerClifford Wolf <clifford@clifford.at>
Fri, 13 Jun 2014 09:29:23 +0000 (11:29 +0200)
frontends/ast/ast.cc
frontends/ast/ast.h
frontends/verilog/lexer.l
frontends/verilog/parser.y

index 0780f7b59fd19dfb0e875975995d664d0ee67d3b..1ce7efc84d60f9c7031c76e3f5f43904e316c691 100644 (file)
@@ -77,6 +77,7 @@ std::string AST::type2str(AstNodeType type)
        X(AST_ARGUMENT)
        X(AST_RANGE)
        X(AST_CONSTANT)
+       X(AST_REALVALUE)
        X(AST_CELLTYPE)
        X(AST_IDENTIFIER)
        X(AST_PREFIX)
@@ -460,6 +461,10 @@ void AstNode::dumpVlog(FILE *f, std::string indent)
                        fprintf(f, "%zd'b %s", bits.size(), RTLIL::Const(bits).as_string().c_str());
                break;
 
+       case AST_REALVALUE:
+               fprintf(f, "%e", realvalue);
+               break;
+
        case AST_BLOCK:
                if (children.size() == 1) {
                        children[0]->dumpVlog(f, indent);
index 802bf98ffe720bace810af11effbdfdbc62d6ad8..aeb56e352de8d471d0820e9353adf9fffc417294 100644 (file)
@@ -55,6 +55,7 @@ namespace AST
                AST_ARGUMENT,
                AST_RANGE,
                AST_CONSTANT,
+               AST_REALVALUE,
                AST_CELLTYPE,
                AST_IDENTIFIER,
                AST_PREFIX,
@@ -153,6 +154,7 @@ namespace AST
                bool is_input, is_output, is_reg, is_signed, is_string, range_valid;
                int port_id, range_left, range_right;
                uint32_t integer;
+               double realvalue;
 
                // this is set by simplify and used during RTLIL generation
                AstNode *id2ast;
index 8f4b499164c3ebeaa8ef2240a6fd4a4b8eee6cf0..ed304572bc6f5241a8033347b5ccfece98b008f9 100644 (file)
@@ -179,6 +179,16 @@ namespace VERILOG_FRONTEND {
        return TOK_CONST;
 }
 
+[0-9][0-9_]*\.[0-9][0-9_]*([eE][-+]?[0-9_]+)? {
+       frontend_verilog_yylval.string = new std::string(yytext);
+       return TOK_REAL;
+}
+
+[0-9][0-9_]*[eE][-+]?[0-9_]+ {
+       frontend_verilog_yylval.string = new std::string(yytext);
+       return TOK_REAL;
+}
+
 \"             { BEGIN(STRING); }
 <STRING>\\.    { yymore(); }
 <STRING>\"     {
index cce8a8c405d7abab430d1437fbf0f0b7aa184ffe..e51712b3f4e0988a647f2cff5219bf0143c0a1d1 100644 (file)
@@ -35,7 +35,7 @@
 
 %{
 #include <list>
-#include <assert.h>
+#include <string.h>
 #include "verilog_frontend.h"
 #include "kernel/log.h"
 
@@ -94,7 +94,7 @@ static void free_attr(std::map<std::string, AstNode*> *al)
        bool boolean;
 }
 
-%token <string> TOK_STRING TOK_ID TOK_CONST TOK_PRIMITIVE
+%token <string> TOK_STRING TOK_ID TOK_CONST TOK_REAL TOK_PRIMITIVE
 %token ATTR_BEGIN ATTR_END DEFATTR_BEGIN DEFATTR_END
 %token TOK_MODULE TOK_ENDMODULE TOK_PARAMETER TOK_LOCALPARAM TOK_DEFPARAM
 %token TOK_INPUT TOK_OUTPUT TOK_INOUT TOK_WIRE TOK_REG
@@ -221,7 +221,7 @@ module:
                        frontend_verilog_yyerror("Missing details for module port `%s'.",
                                        port_stubs.begin()->first.c_str());
                ast_stack.pop_back();
-               assert(ast_stack.size() == 0);
+               log_assert(ast_stack.size() == 0);
        };
 
 module_para_opt:
@@ -1133,6 +1133,17 @@ basic_expr:
                        log_error("Value conversion failed: `%s'\n", $1->c_str());
                delete $1;
        } |
+       TOK_REAL {
+               $$ = new AstNode(AST_REALVALUE);
+               char *p = strdup($1->c_str()), *q;
+               for (int i = 0, j = 0; !p[j]; j++)
+                       if (p[j] != '_')
+                               p[i++] = p[j], p[i] = 0;
+               $$->realvalue = strtod(p, &q);
+               log_assert(*q == 0);
+               delete $1;
+               free(p);
+       } |
        TOK_STRING {
                $$ = AstNode::mkconst_str(*$1);
                delete $1;