Click here to Skip to main content
15,890,336 members
Articles / Programming Languages / C#

Improved Code Generator for PPL

Rate me:
Please Sign up or sign in to vote.
5.00/5 (2 votes)
14 Nov 2023MIT2 min read 4.3K   1   2
What is PPL, PatternJson library, examples
The PPL language employs parentheses for statements, parameters, and blocks, enhancing parsing but posing challenges in programming. To address this, a conversion step translates script (scr) notation into parentheses notation (ppl) through patterns.json and keywords.json files, facilitating program writing. This post discusses internals, contents and gives code samples of using Code Generator for PPL

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
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
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

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

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:

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

License

This article, along with any associated source code and files, is licensed under The MIT License


Written By
Software Developer (Senior)
Slovenia Slovenia
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralMy vote of 5 Pin
Ștefan-Mihai MOGA14-Nov-23 13:12
professionalȘtefan-Mihai MOGA14-Nov-23 13:12 
GeneralRe: My vote of 5 Pin
Oscar Kogosov 202314-Nov-23 21:23
Oscar Kogosov 202314-Nov-23 21:23 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.