Open-source image
open-source
Hime logo

Table of content

Quickstart for C#

This guide gets you started with Hime using C#. It is also available for Java and Rust. The program here is to download the tooling, get a prepared grammar, compile it with himecc and use the generated parser.

Pre-requisites for this guide are:
  • A local installation of a compatible .Net platform such as:
    • The .Net Framework 2.0 or higher on Windows (installed by default on Windows Vista and up).
    • Mono 4.6 or higher on Linux and MacOS.
    • .Net Core 2.0 or higher on a compatible OS.

Get the tooling

The parser generator for Hime can be found on the download page.
Step 1 Download himecc for your system.
You may want some editing support for Hime grammars. In this case, head to the editors line-up page. For an IDE experience, we recommend the Visual Studio Code extension.

Get the grammar

Step 2 Create and open a file named MathExp.gram.
Step 3 Then copy-paste in this file the following grammar:

grammar MathExp
{
  options
  {
    Axiom = "exp"; // the top variable for this grammar
    Separator = "SEPARATOR"; // the terminal that represent white space
  }
  terminals
  {
    WHITE_SPACE -> U+0020 | U+0009 | U+000B | U+000C ;
    SEPARATOR   -> WHITE_SPACE+;

    INTEGER     -> [1-9] [0-9]* | '0' ;
    REAL        -> INTEGER? '.' INTEGER  (('e' | 'E') ('+' | '-')? INTEGER)?
                |  INTEGER ('e' | 'E') ('+' | '-')? INTEGER ;
    NUMBER      -> INTEGER | REAL ;
  }
  rules
  {
    exp_atom   -> NUMBER
               | '(' exp ')' ;
    exp_factor -> exp_atom
               |  exp_factor '*' exp_atom
               |  exp_factor '/' exp_atom ;
    exp_term   -> exp_factor
               |  exp_term '+' exp_factor
               |  exp_term '-' exp_factor ;
    exp        -> exp_term ;
  }
}

Compile the grammar

Step 4 Compile the MathExp.gram:

  • On Windows: himecc.exe MathExp.gram
  • On Linux and MacOS: himecc MathExp.gram

The tool will generate 4 files:

  • MathExpLexer.cs, the source file for the lexer
  • MathExpLexer.bin, the binary representation of the lexer’s automaton
  • MathExpParser.cs, the source file for the parser
  • MathExpParser.bin, the binary representation of the parser’s automaton

Note here that the default target for himecc is the .Net platform; so that we did not had to explicitly set the target. For a complete guide to the options of himecc, head to the reference page.

Setup the test project

Step 5 Setup a test project; either as a .Net Core app, or as a .Net Framework application. Use the following project layout:

test/
+-> test.csproj
+-> Program.cs
+-> MathExpLexer.cs
+-> MathExpLexer.bin
+-> MathExpParser.cs
+-> MathExpParser.bin

Step 6 Set the minimal test.csproj:

<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
    <PropertyGroup>
    <SchemaVersion>2.0</SchemaVersion>
    <OutputType>Exe</OutputType>
    <RootNamespace>TestHime</RootNamespace>
    <AssemblyName>TestHime</AssemblyName>
    <!-- change this to netcoreapp2.0 for a .Net Core application -->
    <TargetFrameworks>net461</TargetFrameworks>
    <Version>1.0.0</Version>
    </PropertyGroup>
    <ItemGroup>
        <!-- so that MathExpLexer.bin MathExpParser.bin are included -->
        <EmbeddedResource Include="*.bin" />
    </ItemGroup>
    <ItemGroup>
        <!-- reference to the .Net runtime for generated parsers -->
        <PackageReference Include="Hime.Redist" Version="4.0.0"/>
    </ItemGroup>
</Project>

To produce a .Net Core application instead of a .Net Framework or Mono application, simply replace net461 by netcoreapp2.0 in the <TargetFrameworks> tag.

Step 7 Set the minimal Program.cs:

using System;
using Hime.Redist; // the namespace for the Hime Runtime
using MathExp; // default namespace for the parser is the grammar's name

namespace TestHime
{
    class Program
    {
        public static void Main(string[] args)
        {
            // Creates the lexer and parser
            MathExpLexer lexer = new MathExpLexer("2 + 3");
            MathExpParser parser = new MathExpParser(lexer);
            // Executes the parsing
            ParseResult result = parser.Parse();
            // Prints the produced syntax tree
            Print(result.Root, new bool[] {});
        }

        private static void Print(ASTNode node, bool[] crossings)
        {
            for (int i = 0; i < crossings.Length - 1; i++)
                Console.Write(crossings[i] ? "|   " : "    ");
            if (crossings.Length > 0)
                Console.Write("+-> ");
            Console.WriteLine(node.ToString());
            for (int i = 0; i != node.Children.Count; i++)
            {
                bool[] childCrossings = new bool[crossings.Length + 1];
                Array.Copy(crossings, childCrossings, crossings.Length);
                childCrossings[childCrossings.Length - 1] = (i < node.Children.Count - 1);
                Print(node.Children[i], childCrossings);
            }
        }
    }
}

Build and execute the test project

Step 8 Build the test project:

  • Using the .Net Framework or Mono:nuget restore
    Then:msbuild
  • Using .Net Core:dotnet restore
    Then:dotnet build

Step 9 Execute the test project:

  • Using the .Net Framework or Mono:bin/Debug/net461/TestHime.exe, or with Monomono bin/Debug/net461/TestHime.exe
  • Using .Net Core:dotnet bin/Debug/netcoreapp2.0/TestHime.dll

The output of the program should a text printout of the produced syntax tree be as follow:

exp
+-> exp_term
    +-> exp_term
    |   +-> exp_factor
    |       +-> exp_atom
    |           +-> NUMBER = 2
    +-> + = +
    +-> exp_factor
        +-> exp_atom
            +-> NUMBER = 3

This concludes this guide. For a more complete tutorial, head over to the the first C# tutorial.