---
title: "Dependency parsing in C#"
url: https://recursiveai.org/onenlp/cookbook/dependency-parsing/
description: "Link words to their grammatical heads to find subjects and modifiers."
version: "1.0.0"
---

# Dependency parsing in C#

**OneNLP** is a free, open-source natural language processing library for .NET from Recursive AI. MIT or Apache-2.0, no native dependencies.

[NuGet](https://www.nuget.org/packages/RecursiveAI.OneNlp.Models.English) · [GitHub](https://github.com/recursive-ai-oss/onenlp-csharp) · [Docs](https://recursiveai.org/onenlp/docs/) · [Download example (.zip)](https://recursiveai.org/onenlp/cookbook/dependency-parsing/dependency-parsing.zip)

Link words to their grammatical heads to find subjects and modifiers.

```shell
dotnet add package RecursiveAI.OneNlp.Models.English
```

Requires [.NET 10](https://dotnet.microsoft.com/download/dotnet/10.0) (net10.0); .NET 9 and earlier aren’t supported.

```csharp
using RecursiveAI.OneNlp;

Doc doc = Nlp.Analyze(
    "The cat sleeps.", Language.English);
foreach (Token token in doc)
    Console.WriteLine(
        $"{token.Text}: {token.Dep}" +
        $" -> {token.Head.Text}");
```

```text
The: det -> cat
cat: nsubj -> sleeps
sleeps: root -> sleeps
.: punct -> sleeps
```

Unzip [the example](https://recursiveai.org/onenlp/cookbook/dependency-parsing/dependency-parsing.zip), then `dotnet run`.

## Full program

The program analyzes “The cat sleeps.” and prints each token’s dependency label and head word. “cat” is the subject of “sleeps”; “The” modifies “cat”. The root token points to itself in the public token API.

The download’s `Program.cs` is the snippet above.

`dotnet run` prints:

```text
The: det -> cat
cat: nsubj -> sleeps
sleeps: root -> sleeps
.: punct -> sleeps
```

With only the core package, `Analyze` does not supply trained dependency annotations; reference the English model package for this example.

## Variations

**Extract noun phrases.** `Doc.NounChunks` returns base noun phrases derived from the parse. This standalone snippet prints the phrase, not its individual tokens.

```csharp
using RecursiveAI.OneNlp;

Doc doc = Nlp.Analyze("The cat sleeps.", Language.English);
foreach (var phrase in doc.NounChunks)
    Console.WriteLine(phrase.Text);
```

```text
The cat
```

## Related recipes

- [Part-of-speech tagging in C#](https://recursiveai.org/onenlp/cookbook/part-of-speech-tagging/)
- [Generate sentence embeddings in C#](https://recursiveai.org/onenlp/cookbook/sentence-embeddings/)

## The short answer

For dependency parsing in C#, reference `RecursiveAI.OneNlp.Models.English` and analyze text with `Nlp.Analyze(text, Language.English)`. Each token has a dependency relation in `Dep`, a head token in `Head` and its head’s document index in `HeadIndex`. The program above prints a small tree as readable token-to-head links.

The English model supplies the trained parser. The core library alone supplies segmentation but does not infer dependency relations. Keep the model package in your project even if your code only mentions core API types. The [model package guide](https://recursiveai.org/onenlp/docs/model-packages/) explains how models register with the API.

## What is an example of dependency parsing in C#?

In “The cat sleeps.”, “sleeps” is the root, “cat” is its subject and “The” is a determiner attached to “cat”. Punctuation also has a dependency relation. The output includes every token so that you can inspect the entire result rather than just the subject you hoped to find.

Use token indices when storing edges. Words can repeat in a sentence, so the head’s text is useful for a walkthrough but is not a unique identifier. Retain the original document and the token indices together when building a graph or highlighting a relationship in a UI. The [parser documentation](https://recursiveai.org/onenlp/docs/parser/) describes how the model produces heads and relations.

The API’s root representation is also worth keeping separate from a file format’s conventions. In this example, the root token’s public `Head` is itself. An exporter may represent the root differently. Do not reinterpret every head value as a position in the original character string; token positions and character positions serve different purposes.

## Is dependency parsing transition-based?

OneNLP’s documented parser is graph-based. It scores head relationships and decodes a maximum spanning tree, with one root per sentence. Its documentation explicitly says a transition-based design was not implemented. That is an architectural distinction, not a claim that one family is universally better.

Sentence boundaries matter because the parser builds a tree for each sentence. Existing boundaries are used; otherwise its boundary classifier supplies them. The documented parser splits sentences longer than 400 tokens into pieces of 400. If your application relies on a relation spanning an exceptionally long sentence, that behavior matters more than simply checking whether the call returned a document.

These are predictions from a trained model, not guaranteed facts about the text. Test the constructions your application cares about, especially fragments and domain-specific writing. A syntactically valid output tree is not the same thing as a correct interpretation.

## What is the difference between constituency parsing and dependency parsing?

Dependency parsing returns word-to-head relationships. A constituency tree represents nested phrases instead; the dependency example here does not return such a tree. To get flat noun phrases from the dependency result, read `Doc.NounChunks`, as in the variation. It derives base noun phrases from parts of speech, heads and relations. “The cat” is returned as one phrase here. The phrase does not include the sentence’s verb or its final punctuation.

Noun chunks are flat phrases rather than a complete nested phrase tree. The documented rules choose phrase heads, extend across certain dependents and avoid overlapping phrases. Use them for a compact list of noun phrases; use individual dependency edges when you need the actual grammatical relationships. The [noun chunk rules](https://recursiveai.org/onenlp/docs/parser/#noun-chunks) describe that distinction and the supported relation handling.
