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
"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
- Files Patterns.json and Keywords.json are created in directory Json.
- 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
- Create project
PJ
, add generated in p.2 files and DLLs: PatternJson.Dll, NewtonsoftJson.DLL from Nuget Packages. - Add code to generated methods.
- Compile project
PJ
. - Create file in format scr (TestPJ.scr).
- 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