rsdn / nitra

Nitra is a language workbench

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Assertion Exception when parsing grammar

ssrmm opened this issue · comments

commented

The following grammar produces an assertion error during parsing (i.e. showing a modal modal dialog that has to be clicked away):

namespace Test
{
  syntax module Test
  {
    using Nitra.Core;

    [StartRule]
    syntax Expression = (Foo ';' nl)+;

    token Foo
    {
      regex Foo = "foo";
    }
  }
}

I'm not really sure if that's actually a supported syntax. But either way it should behave differently: If it is syntactically valid, it should work; if it isn't, there should be an error at compile-time, not an assertion error at runtime.

As a side-note:

token Foo = Foo
{
  regex Foo = "foo";
}

does work, so it seems reasonable to me that the shorthand syntax should be valid as well.


Stacktrace of the assertion:

at Nitra.Internal.Recovery.TokenChanges..ctor(Int32 inserted, Int32 deleted) in C:\NitraBase\Nitra\Nitra\Nitra.Runtime\Internal\Recovery\TokenChanges.n:Line 25.
at Nitra.Internal.Recovery.RecoveryParser.InsertSubrules(Int32 maxPos) in C:\NitraBase\Nitra\Nitra\Nitra.Runtime\Internal\Recovery\RecoveryParser\RecoveryParser.Insert.n:Line 47.
at Nitra.Internal.Recovery.RecoveryParser.RecoveryFromAllErrors() in C:\NitraBase\Nitra\Nitra\Nitra.Runtime\Internal\Recovery\RecoveryParser\RecoveryParser.n:Line 126.
at Nitra.ParseSession._N__N_lambda__33699__33715.apply_void(IParseResult parseResult) in C:\NitraBase\Nitra\Nitra\Nitra.Runtime\Parsing\ParseSession.n:Line 82.
at Nitra.ParseResult.ParseImpl() in C:\NitraBase\Nitra\Nitra\Nitra.Runtime\Parsing\ParseResult.n:Line 116.
at Nitra.ParseResult.Parse() in C:\NitraBase\Nitra\Nitra\Nitra.Runtime\Parsing\ParseResult.n:Line 70.
at Nitra.ParseSession.Parse(SourceSnapshot sourceSnapshot) in C:\NitraBase\Nitra\Nitra\Nitra.Runtime\Parsing\ParseSession.n:Line 106.
at Nitra.ParseSession.Parse(String sourceText) in C:\NitraBase\Nitra\Nitra\Nitra.Runtime\Parsing\ParseSession.n:Line 88.
at TesstApp.Program.Main(String[] args) in d:\<...>\Program.cs:Line 24.

Stacktrace of the Nitra.ParsingFailureException that is produced afterwards, probably as a result of the failed assertion

Unexpected token: 'a'
   at Nitra.ParseResult.ParseImpl() in C:\NitraBase\Nitra\Nitra\Nitra.Runtime\Parsing\ParseResult.n:Line 130.
   at Nitra.ParseResult.Parse() in C:\NitraBase\Nitra\Nitra\Nitra.Runtime\Parsing\ParseResult.n:Line 70.
   at Nitra.ParseSession.Parse(SourceSnapshot sourceSnapshot) in C:\NitraBase\Nitra\Nitra\Nitra.Runtime\Parsing\ParseSession.n:Line 105.
   at Nitra.ParseSession.Parse(String sourceText) in C:\NitraBase\Nitra\Nitra\Nitra.Runtime\Parsing\ParseSession.n:Line 88.
   at TesstApp.Program.Main(String[] args) in d:\<..>\Program.cs:Line 24.

I've used the following test program along with a configuration entry that "redirects" the error message of the popups to a logfile (see https://msdn.microsoft.com/en-us/library/ty5e4c4h.aspx)

using System;
using Nitra;
using Nitra.ProjectSystem;

namespace TesstApp
{
    public class Program
    {
        public static void Main(string[] args)
        {
            Console.Write("> ");
            var input = Console.ReadLine();

            while (input != string.Empty)
            {
                try
                {
                    var session = new ParseSession(Test.Test.Expression, compilerMessages: new ConsoleCompilerMessages());

                    var result = session.Parse(input);

                    if (result.IsSuccess)
                    {
                        Console.WriteLine("Parsing succeeded!");
                    }
                    else
                    {
                        Console.Error.WriteLine("Parsing failed!");
                    }

                    Console.WriteLine("PrettyPrint: " + result.CreateParseTree());
                }
                catch (Exception e)
                {
                    Console.Error.WriteLine("An exception of type {0} was not handled.", e.GetType());
                    Console.Error.WriteLine(e.Message);
                    Console.Error.WriteLine(e.StackTrace);
                }

                Console.Write("> ");
                input = Console.ReadLine();
            }
        }
    }
}