Skip to content
This repository was archived by the owner on Oct 28, 2023. It is now read-only.

Example Pascal

Christophe VG edited this page Mar 6, 2017 · 1 revision

In the example/pascal folder development started by writing a manual implementation for the embryonal Pascal example, pascal.cs, taking into account this could be generated. The output of the example program, parses the example Pascal file and outputs an AST-like structure.

The example Pascal program, taken from the EBNF Wikipedia page, looks like this:

 PROGRAM DEMO1
 BEGIN
   A:=3;
   B:=45;
   H:=-100023;
   C:=A;
   D123:=B34A;
   BABOON:=GIRAFFE;
   TEXT:="Hello world!";
 END.

The Manual target of the build file compiles the manual implementation and runs it, producing a string-representation of the resulting AST:

$ cd example/pascal

$ xbuild /target:Manual
XBuild Engine Version 14.0
Mono, Version 4.6.2.0
Copyright (C) 2005-2013 Various Mono authors

Build started 3/6/2017 12:57:17 PM.
__________________________________________________
Project "/Users/xtof/Workspace/human-parser-generator/example/pascal/pascal.csproj" (Manual target(s)):
	Target Manual:
		Tool /Library/Frameworks/Mono.framework/Versions/4.6.2/lib/mono/4.5/mcs.exe execution started with arguments:  /debug+ /out:bin/Debug/pascal-manual.exe ../../generator/parsable.cs ../../generator/dump-ast.cs pascal-manual.cs /target:exe
		Executing: mono bin/Debug/pascal-manual.exe example.pascal | LC_ALL="C" astyle -s2 -xt0 -xe -Y -xC80
		new Program() {
		  Identifier = new Identifier() { Name = "DEMO1"},
		  Assignments = new List<Assignment>() {
		    new Assignment() {
		      Identifier = new Identifier() { Name = "A"},
		      Expression = new Number() {
		        Value = "3"
		      }
		    },new Assignment() {
		      Identifier = new Identifier() { Name = "B"},
		      Expression = new Number() {
		        Value = "45"
		      }
		    },new Assignment() {
		      Identifier = new Identifier() { Name = "H"},
		      Expression = new Number() {
		        Value = "-100023"
		      }
		    },new Assignment() {
		      Identifier = new Identifier() { Name = "C"},
		      Expression = new Identifier() {
		        Name = "A"
		      }
		    },new Assignment() {
		      Identifier = new Identifier() { Name = "D123"},
		      Expression = new Identifier() {
		        Name = "B34A"
		      }
		    },new Assignment() {
		      Identifier = new Identifier() { Name = "BABOON"},
		      Expression = new Identifier() {
		        Name = "GIRAFFE"
		      }
		    },new Assignment() {
		      Identifier = new Identifier() { Name = "TEXT"},
		      Expression = new String() {
		        Text = "Hello world!"
		      }
		    }
		  }
		}
Done building project "/Users/xtof/Workspace/human-parser-generator/example/pascal/pascal.csproj".

Build succeeded.
	 0 Warning(s)
	 0 Error(s)

Time Elapsed 00:00:00.9019200

I've chosen to implement the ToString() functionality of the AST as C# code that builds the same data structure. This is easy to reuse it, e.g. in unit tests and it formats nicely (using e.g. AStyle).

Next, the build file also implements a generated Pascal parser, from a grammar language definition. This grammar, also acquired from the EBNF Wikipedia page looks like this (after modifications to use the extended possibilities of the [HPG Grammar](HPG Grammar):

(* a simple program syntax in HPG-flavoured EBNF - based on example from Wikipedia *)

program      = "PROGRAM" identifier
               "BEGIN"
               { assignment ";" }
               "END."
             ;

assignment   = identifier ":=" expression ;

expression   = identifier
             | string
             | number
             ;

identifier   = name  @ ? /([A-Z][A-Z0-9]*)/ ? ;
string       = text  @ ? /"([^"]*)"|'([^']*)'/ ? ;
number       = value @ ? /(-?[1-9][0-9]*)/ ? ;

Issuing xbuild runs the manual implementation, generates a fresh Pascal parser, compares the manual and generated parser and finally also runs the generated version:

$ xbuild
XBuild Engine Version 14.0
Mono, Version 4.6.2.0
Copyright (C) 2005-2013 Various Mono authors

Build started 3/6/2017 1:03:49 PM.
__________________________________________________
Project "/Users/xtof/Workspace/human-parser-generator/example/pascal/pascal.csproj" (default target(s)):
	Target Manual:
		Tool /Library/Frameworks/Mono.framework/Versions/4.6.2/lib/mono/4.5/mcs.exe execution started with arguments:  /debug+ /out:bin/Debug/pascal-manual.exe ../../generator/parsable.cs ../../generator/dump-ast.cs pascal-manual.cs /target:exe
		Executing: mono bin/Debug/pascal-manual.exe example.pascal | LC_ALL="C" astyle -s2 -xt0 -xe -Y -xC80
		new Program() {
		  Identifier = new Identifier() { Name = "DEMO1"},
		  Assignments = new List<Assignment>() {
		    new Assignment() {
		      Identifier = new Identifier() { Name = "A"},
		      Expression = new Number() {
		        Value = "3"
		      }
		    },new Assignment() {
		      Identifier = new Identifier() { Name = "B"},
		      Expression = new Number() {
		        Value = "45"
		      }
		    },new Assignment() {
		      Identifier = new Identifier() { Name = "H"},
		      Expression = new Number() {
		        Value = "-100023"
		      }
		    },new Assignment() {
		      Identifier = new Identifier() { Name = "C"},
		      Expression = new Identifier() {
		        Name = "A"
		      }
		    },new Assignment() {
		      Identifier = new Identifier() { Name = "D123"},
		      Expression = new Identifier() {
		        Name = "B34A"
		      }
		    },new Assignment() {
		      Identifier = new Identifier() { Name = "BABOON"},
		      Expression = new Identifier() {
		        Name = "GIRAFFE"
		      }
		    },new Assignment() {
		      Identifier = new Identifier() { Name = "TEXT"},
		      Expression = new String() {
		        Text = "Hello world!"
		      }
		    }
		  }
		}
	Target HPG:
		Project "/Users/xtof/Workspace/human-parser-generator/hpg.csproj" (default target(s)):
			Target Gen0Parser:
				Tool /Library/Frameworks/Mono.framework/Versions/4.6.2/lib/mono/4.5/mcs.exe execution started with arguments:  /debug+ /out:bin/Debug/hpg.gen0.exe generator/parsable.cs generator/generator.cs generator/factory.cs generator/emitter.csharp.cs generator/emitter.bnf.cs generator/format.csharp.cs generator/AssemblyInfo.cs generator/grammar.cs generator/bootstrap.cs /target:exe
			Target Gen1Source:
				Executing: mono bin/Debug/hpg.gen0.exe generator/hpg.bnf | LC_ALL="C" astyle -s2 -xt0 -xe -Y -xC80 > generator/parser.gen1.cs
			Target Gen1Parser:
				Tool /Library/Frameworks/Mono.framework/Versions/4.6.2/lib/mono/4.5/mcs.exe execution started with arguments:  /debug+ /out:bin/Debug/hpg.gen1.exe generator/parsable.cs generator/generator.cs generator/factory.cs generator/emitter.csharp.cs generator/emitter.bnf.cs generator/format.csharp.cs generator/AssemblyInfo.cs generator/parser.gen1.cs generator/hpg.cs /target:exe
			Target HPGSource:
				Executing: mono bin/Debug/hpg.gen1.exe generator/hpg.bnf | LC_ALL="C" astyle -s2 -xt0 -xe -Y -xC80 > generator/parser.cs
			Target Build:
				Tool /Library/Frameworks/Mono.framework/Versions/4.6.2/lib/mono/4.5/mcs.exe execution started with arguments:  /debug+ /out:bin/Debug/hpg.exe generator/parsable.cs generator/generator.cs generator/factory.cs generator/emitter.csharp.cs generator/emitter.bnf.cs generator/format.csharp.cs generator/AssemblyInfo.cs generator/parser.cs generator/hpg.cs /target:exe
		Done building project "/Users/xtof/Workspace/human-parser-generator/hpg.csproj".
	Target Generated:
		Executing: mono ../../bin/Debug//hpg.exe -i pascal.bnf | LC_ALL="C" astyle -s2 -xt0 -xe -Y -xC80 > pascal.cs
	Target Compare:
		Executing: cat pascal-manual.cs | LC_ALL="C" astyle -s2 -xt0 -xe -Y -xC80 > manual.cs
		Executing: diff -u -w  manual.cs pascal.cs
		Executing: rm manual.cs
	Target BuildGenerated:
		Tool /Library/Frameworks/Mono.framework/Versions/4.6.2/lib/mono/4.5/mcs.exe execution started with arguments:  /debug+ /out:bin/Debug/parse-pascal.exe ../../generator/parsable.cs ../../generator/dump-ast.cs pascal.cs /target:exe
	Target RunGenerated:
		Executing: mono bin/Debug/parse-pascal.exe example.pascal | LC_ALL="C" astyle -s2 -xt0 -xe -Y -xC80
		new Program() {
		  Identifier = new Identifier() { Name = "DEMO1"},
		  Assignments = new List<Assignment>() {
		    new Assignment() {
		      Identifier = new Identifier() { Name = "A"},
		      Expression = new Number() {
		        Value = "3"
		      }
		    },new Assignment() {
		      Identifier = new Identifier() { Name = "B"},
		      Expression = new Number() {
		        Value = "45"
		      }
		    },new Assignment() {
		      Identifier = new Identifier() { Name = "H"},
		      Expression = new Number() {
		        Value = "-100023"
		      }
		    },new Assignment() {
		      Identifier = new Identifier() { Name = "C"},
		      Expression = new Identifier() {
		        Name = "A"
		      }
		    },new Assignment() {
		      Identifier = new Identifier() { Name = "D123"},
		      Expression = new Identifier() {
		        Name = "B34A"
		      }
		    },new Assignment() {
		      Identifier = new Identifier() { Name = "BABOON"},
		      Expression = new Identifier() {
		        Name = "GIRAFFE"
		      }
		    },new Assignment() {
		      Identifier = new Identifier() { Name = "TEXT"},
		      Expression = new String() {
		        Text = "Hello world!"
		      }
		    }
		  }
		}
Done building project "/Users/xtof/Workspace/human-parser-generator/example/pascal/pascal.csproj".

Build succeeded.
	 0 Warning(s)
	 0 Error(s)

Time Elapsed 00:00:03.1727410

Clone this wiki locally