65.9K
CodeProject is changing. Read more.
Home

Improved Code Generator for PPL

starIconstarIconstarIconstarIconstarIcon

5.00/5 (2 votes)

Nov 14, 2023

MIT

2 min read

viewsIcon

4711

What is PPL, PatternJson library, examples

Introduction

Elements of the PPL language (statements, parameters, blocks) are enclosed in parentheses, which makes it easy to parse them, but it is difficult to write a program in such a language. Therefore, the PPL includes an additional step, which converts the script (scr) notation into parentheses notation (ppl), which is then processed by means of the PPL language.

Example

   array (y) (1)(2)(3); ppl notation
   array y[] = {1,2,3}; scr notation  

This translation is carried out as follows.
There are three types of elements that are translated into PPL, format their elements:

Keyword statement:= <keyword>  <text>;
Non-keyword statement:= <text>;
Block statement:= <keyword> <text> { Keyword statements |  Non-keyword statements }

Translation is carried out in accordance with the rules defined in 2 files: patterns.json and keywords.json.

File Patterns.json

     <pattern>:  <name> <description array> 
     <description item>:  <name>  | * |  <delimiter> <value>   

Example

scr_code
 var x = 1;
Patterns.json
 "name":= "pattern_name=",
          "description": [
            {  "name": "name" },
            {  "name": "delimiter", "value": "="  },
            {  "name": "value"}
          ]

´*´ is used to define array, its value is separator between array items:

Example

scr code
array y[] = {1,2,3};
Patterns.json
"name": "pattern_list",
    "description": [
      { "name": "name" },
      { "name": "delimiter",   "value": "="  },     
      { "name": "delimiter",   "value": "{" },
      { "name": "*",        "value": "," },
      { "name": "delimiter",   "value": "}" }
    ]

File Keywords.json

     <keyword>:= <name> <block> <patterns array>
     <block>:= <true | false> 
     <block> is true true for blocked statement and false for non- blocked statement.

Patterns array contains names of patterns from file Patterns.json.
Project PJ contains three subprojects.
GenPJ: EXE - to generate code for project PJ.
PatternJson: DLL – class for generation code project PJ and for ResultCode.ppl
PJ: EXE – for creation ResultCode.ppl

  1. Files Patterns.json and Keywords.json are created in directory Json.
  2. Run application GenPJ.exe to create processing methods for each keyword and the following additional methods, called during Traversal in directory GeneratedCode:
    • EntryToProcessing
    • ExitFromProcessing
    • ExitFromBlock
    • Non-keywordProcessing
  3. Create project PJ, add generated in p.2 files and DLLs: PatternJson.Dll, NewtonsoftJson.DLL from Nuget Packages.
  4. Add code to generated methods.
  5. Compile project PJ.
  6. Create file in format scr (TestPJ.scr).
  7. Run PJ.exe for translation file.scr to file.ppl (ResultCode.ppl).

PJ.exe creates AST, passes all AST elements, chooses the right pattern for each keyword from input file and carries out sequence of functions in accordance with type of element.

AST Structure

Nodes -> Block statements
Leafs -> Keyword statements | Non-keyword statements
Function call sequence for each type  of elements:
Keyword statement:
EntryToProcessing  -> Keyword statementProcessing  ->ExitFromProcessing
Block statement:
EntryToProcessing  ->Block statementProcessing ->ExitFromProcessing  -> ExitFromBlock   
Non-keyword statement: 
Non-keywordProcessing  - processing for all  Non-keyword statements  

Example

Translation from scr to ppl

Keyword.json

      [
      {
          "name" : "var",
          "block": false,
          "patterns": [
              "pattern_name",
              "pattern_name="
          ]   
      },
      {
          "name" :"set",
          "block": false,
          "patterns": [
              "pattern_name="
          ]  
      },
      {
          "name" :"array",
          "block": false,
          "patterns": [
              "pattern_name",
              "pattern_name=",
              "pattern_list"
          ] 
      },
      {
          "name" :"function",
          "block": true,
          "patterns": [
              "pattern_function"
          ] 
      },
      {
          "name" :"for",
          "block": true,
          "patterns": [
              "pattern_for1",
              "pattern_for2"
          ] 
      }
  ]

Pattern.json

[
  {
    "name": "pattern_name",
    "description": [
      {  "name": "name" }
    ]
  },
  {
    "name": "pattern_name=",
    "description": [
      {  "name": "name" },
      {  "name": "delimiter", "value": "="  },
      {  "name": "value"}
    ]
  },
  {
    "name": "pattern_name=,",
    "description": [
      {  "name": "name" },
      {  "name": "delimiter", "value": "="  },
      {  "name": "value1"},
      {  "name": "delimiter", "value": "," },
      {  "name": "value2" }
    ]
  },
  {
   "name": "pattern_list",
    "description": [
      { "name": "name" },
      { "name": "delimiter",   "value": "="  },     
      { "name": "delimiter",   "value": "{" },
      { "name": "*",        "value": "," },
      { "name": "delimiter",   "value": "}" }
    ]
  },

  {
    "name": "pattern_function",
    "description": [
      {  "name": "name" },
      {  "name": "delimiter",  "value": "(" },
      {  "name": "params"},
      {  "name": "delimiter",  "value": ")" }
    ]
  },
  {
    "name": "pattern_for1",
    "description": [
      { "name": "delimiter", "value": "("  },
      { "name": "loop_var" },
      { "name": "delimiter", "value": ","  },
      { "name": "begin" },
      { "name": "delimiter", "value": ","  },
      { "name": "end" },
      { "name": "delimiter", "value": ")"  }
    ]
  },
  {
    "name": "pattern_for2",
    "description": [
      {  "name": "delimiter",  "value": "(" },
      {  "name": "loop_var" },
      {  "name": "delimiter",  "value": ","  },
      {  "name": "begin" },
      {  "name": "delimiter",  "value": "," },
      {  "name": "end" },
      {  "name": "delimiter",  "value": "," },
      {  "name": "increment" },
      {  "name": "delimiter",  "value": ")" },  
    ]
  }
]

Generated functions: FuncArray.cs, FuncFor.cs, FuncFunction.cs, FuncVar.cs, FuncSet.cs, KeywordFunctions, PJ.cs.
Generated code - see in directory GeneratedCode.
Generated functions with added code for processing - see in project PJ.

TestPJ.scr

recreate yes;
array a;
array b = {1,2,3};
array c = 0;

var c;
var k = 0;
for (i,0,3,1) 
{ 
  write("loop1");
  var x = 0; 
  set x = 1; 
  for (j,1,4,1)
  {
      write("loop2");
      var y = 2; 
      set y = 3; 
  } 
} 

In this code:

Keyword statements: 		var, set, array
Block statement: 		for
Non-keyword statements:	recreate, write

Result in ResultCode.ppl:

recreate yes;
array (a);
array (b) (1)(2)(3);
array (c)(0);
var(c);
var(k[0]);
loop (i) (0) (3) (1)
(
  do 
  (
  (write("loop1"))
  (var(x[0]))
  (set(x)(1))
  (  loop (j) (1) (4) (1)
  (
    do 
    (
    (write("loop2"))
    (var(y[2]))
    (set(y)(3))
    )
  )
  )
  )
 );

Conclusion

DLL PatternJson may be used for other code conversions.

History

  • 14th November, 2023: Initial version