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