Difference between revisions of "How to parse a string"

From Verific Design Automation FAQ
Jump to: navigation, search
(Created page with "Let's say you want to add a node to the parsetree. One of the simple ways to do so is to start with a text string; then "parse" that string to get a VHDL or Verilog construct...")
 
Line 1: Line 1:
Let's say you want to add a node to the parsetree.
+
Let's say you want to add a node to the parse tree.
  
One of the simple ways to do so is to start with a text string; then "parse" that string to get a VHDL or Verilog construct. The construct then can be added to the parsetree.
+
One simple way to do so is to start with a text string, then "parse" that string to get a VHDL or Verilog construct. The construct then can be added to the parse tree.
  
 
Below are the APIs to parse a string:
 
Below are the APIs to parse a string:
Line 9: Line 9:
 
* VeriModuleItem *veri_file::AnalyzeModuleItem(const char *module_item, unsigned verilog_mode=VERILOG_2K, const linefile_type line_file = 0, VeriScope *container_scope = 0)
 
* VeriModuleItem *veri_file::AnalyzeModuleItem(const char *module_item, unsigned verilog_mode=VERILOG_2K, const linefile_type line_file = 0, VeriScope *container_scope = 0)
 
* VeriStatement *veri_file::AnalyzeStatement(const char *statement, unsigned verilog_mode=VERILOG_2K, const linefile_type line_file = 0, VeriScope *container_scope = 0)
 
* VeriStatement *veri_file::AnalyzeStatement(const char *statement, unsigned verilog_mode=VERILOG_2K, const linefile_type line_file = 0, VeriScope *container_scope = 0)
Appropriate scope information where the given string is valid should be passed to the APIs to have them work properly.
+
Notes for Verilog :
Need to call Resolve() on the returned parse tree nodes with proper scope where these items will be used.
+
:- appropriate scope information where the given string is valid should be passed to the APIs for them to work properly
VeriTreeNode::VERI_UPWARD_SCOPE_NAME can be passed as the resolve environment.
+
:- need to call Resolve() on the returned parse tree nodes with proper scope where these items will be used
If required, they can be added to the existing parse tree using the appropriate APIs.
+
:- VeriTreeNode::VERI_UPWARD_SCOPE_NAME can be passed as the Resolve() environment
 +
:- if required the nodes can be added to the existing parse tree using the appropriate APIs
  
 
'''VHDL:'''
 
'''VHDL:'''
Line 19: Line 20:
 
* VhdlStatement *vhdl_file::AnalyzeConcurrentStatement(const char *statement, unsigned vhdl_mode = VHDL_93, const char *lib_name = "work", const linefile_type line_file = 0, VhdlScope *container_scope = 0)
 
* VhdlStatement *vhdl_file::AnalyzeConcurrentStatement(const char *statement, unsigned vhdl_mode = VHDL_93, const char *lib_name = "work", const linefile_type line_file = 0, VhdlScope *container_scope = 0)
 
* VhdlDesignUnit *vhdl_file::AnalyzeUnit(const char *unit, unsigned vhdl_mode = VHDL_93, const char *lib_name = "work", const linefile_type line_file = 0)
 
* VhdlDesignUnit *vhdl_file::AnalyzeUnit(const char *unit, unsigned vhdl_mode = VHDL_93, const char *lib_name = "work", const linefile_type line_file = 0)
Appropriate scope information where the given string is valid should be passed to the APIs to have them work properly.
+
Notes for VHDL :
We need vhdl_file::AnalyzeSequentialStatement() as well as vhdl_file::AnalyzeConcurrentStatement() to differentiate the starting point between the two.
+
:- appropriate scope information where the given string is valid should be passed to the APIs for them to work properly
Verilog AnalyzeModuleItem() = VHDL AnalyzeConcurrentStatement() and AnalyzeUnit() both
+
:- need vhdl_file::AnalyzeSequentialStatement() as well as vhdl_file::AnalyzeConcurrentStatement() to differentiate between the starting points of the two
Verilog AnalyzeStatement() = VHDL AnalyzeSequentialStatement()
+
:- Verilog AnalyzeModuleItem() = both VHDL AnalyzeConcurrentStatement() and VHDL AnalyzeUnit()
 +
:- Verilog AnalyzeStatement() = VHDL AnalyzeSequentialStatement()
  
 +
An example excerpt of C++ code using AnalyzeExpr() is as follows :
 +
    VeriExpression *expr = veri_file::AnalyzeExpr(expr_string, veri_file::SYSTEM_VERILOG);
 +
    VeriScope *current_scope = module->GetScope() ;
 +
    if (expr) {
 +
        myexp->Resolve(current_scope, VeriTreeNode::VERI_UPWARD_SCOPE_NAME);
 +
        // plus anything else user may want to add
 +
    }
  
Off-course full designs can be analyzed from strings. Please use streams for that.
+
Full designs can be analyzed from strings as well. Please use streams for that.
 
See [https://www.verific.com/docs/index.php?title=Analyzing_Stream_Inputs Analyzing Stream Inputs]
 
See [https://www.verific.com/docs/index.php?title=Analyzing_Stream_Inputs Analyzing Stream Inputs]

Revision as of 16:37, 20 July 2020

Let's say you want to add a node to the parse tree.

One simple way to do so is to start with a text string, then "parse" that string to get a VHDL or Verilog construct. The construct then can be added to the parse tree.

Below are the APIs to parse a string:

Verilog:

  • VeriExpression *veri_file::AnalyzeExpr(const char *expr, unsigned verilog_mode=VERILOG_2K, const linefile_type line_file = 0)
  • VeriModuleItem *veri_file::AnalyzeModuleItem(const char *module_item, unsigned verilog_mode=VERILOG_2K, const linefile_type line_file = 0, VeriScope *container_scope = 0)
  • VeriStatement *veri_file::AnalyzeStatement(const char *statement, unsigned verilog_mode=VERILOG_2K, const linefile_type line_file = 0, VeriScope *container_scope = 0)

Notes for Verilog :

- appropriate scope information where the given string is valid should be passed to the APIs for them to work properly
- need to call Resolve() on the returned parse tree nodes with proper scope where these items will be used
- VeriTreeNode::VERI_UPWARD_SCOPE_NAME can be passed as the Resolve() environment
- if required the nodes can be added to the existing parse tree using the appropriate APIs

VHDL:

  • VhdlExpression *vhdl_file::AnalyzeExpr(const char *expr, unsigned vhdl_mode=VHDL_93, const linefile_type line_file=0)
  • VhdlStatement *vhdl_file::AnalyzeSequentialStatement(const char *statement, unsigned vhdl_mode = VHDL_93, const char *lib_name = "work", const linefile_type line_file = 0, * VhdlScope *container_scope = 0)
  • VhdlStatement *vhdl_file::AnalyzeConcurrentStatement(const char *statement, unsigned vhdl_mode = VHDL_93, const char *lib_name = "work", const linefile_type line_file = 0, VhdlScope *container_scope = 0)
  • VhdlDesignUnit *vhdl_file::AnalyzeUnit(const char *unit, unsigned vhdl_mode = VHDL_93, const char *lib_name = "work", const linefile_type line_file = 0)

Notes for VHDL :

- appropriate scope information where the given string is valid should be passed to the APIs for them to work properly
- need vhdl_file::AnalyzeSequentialStatement() as well as vhdl_file::AnalyzeConcurrentStatement() to differentiate between the starting points of the two
- Verilog AnalyzeModuleItem() = both VHDL AnalyzeConcurrentStatement() and VHDL AnalyzeUnit()
- Verilog AnalyzeStatement() = VHDL AnalyzeSequentialStatement()

An example excerpt of C++ code using AnalyzeExpr() is as follows :

   VeriExpression *expr = veri_file::AnalyzeExpr(expr_string, veri_file::SYSTEM_VERILOG);
   VeriScope *current_scope = module->GetScope() ;
   if (expr) {
       myexp->Resolve(current_scope, VeriTreeNode::VERI_UPWARD_SCOPE_NAME);
       // plus anything else user may want to add
   }

Full designs can be analyzed from strings as well. Please use streams for that. See Analyzing Stream Inputs