Search code examples
c#bnfirony

Irony Parsing a list delimited with white space


I am trying to write a parser for Allen Bradly SLC Language/File format. I have successfully got it to parse a register reference. I.E. N5:4/3. However, when I try to move to to the next level, having it parse a list of register references separated by whitespace, it throws the following error

Input:

N30:3/8 B20:3/3

Error:

(L1, C9) Syntax error, expected: :

Here is my code, this can be built and the dll loaded into the Irony Grammar Explorer

using System;
using Irony.Parsing;

namespace Irony.Samples.SLC
{
    [Language("SLC", "1.0", "RS Logix 500 SLC")]
    public class SLCGrammar : Grammar
    {
        public SLCGrammar()
        {
            //Terminals
            var SLCFilePrefix = new FixedLengthLiteral("Type", 1, TypeCode.String);
            var SLCRegisterWord = new NumberLiteral("Word");
            var SLCRegisterBit = new NumberLiteral("Bit");
            var SLCRegisterFileNumber = new NumberLiteral("FileNumber");


            //Nonterminals      
            var SLCInstructionRegisterList = new NonTerminal("InstructionRegisterList");
            var SLCRegisterReference = new NonTerminal("RegisterReference");
            var SLCRegisterReferenceWordOrBit = new NonTerminal("RegisterReferenceWordOrBit");
            var SLCRegisterReferenceWordWithBit = new NonTerminal("RegisterReferenceWordWithBit");

            //Rules
            SLCRegisterReferenceWordWithBit.Rule = SLCRegisterWord + "/" + SLCRegisterBit;
            SLCRegisterReferenceWordOrBit.Rule = SLCRegisterReferenceWordWithBit | SLCRegisterWord;
            SLCRegisterReference.Rule = SLCFilePrefix + SLCRegisterFileNumber + ":" + SLCRegisterReferenceWordOrBit;
            SLCInstructionRegisterList.Rule = MakePlusRule(SLCInstructionRegisterList, SLCRegisterReference);

            //Set grammar root
            this.Root = SLCInstructionRegisterList;
            //MarkPunctuation(" ");

        }//constructor
    }//class
}//namespace

If I change the following line

SLCInstructionRegisterList.Rule = MakePlusRule(SLCInstructionRegisterList, SLCRegisterReference);

To

SLCInstructionRegisterList.Rule = MakePlusRule(SLCInstructionRegisterList, ToTerm(" "), SLCRegisterReference);

I get

Error: (L1,C9) Syntax error, expected:

Which I assume means it is expecting a space character

Any help would be appreciated. I've just started Learning irony and there isn't a ton of documentation.

Note: Later on I would like to be able to parse a register that takes this form T8:5/DN meaning that after the forward-slash is a string instead of a number. that is terminated is white space


Solution

  • Using the ValidateTokenMethod, and rejecting anything that was not A-Z Solved this issue.

    The problem was that / was being interpreted as the start of a new Register Reference

    var SLCFilePrefix = new FixedLengthLiteral("Type", 1, TypeCode.String);
    SLCFilePrefix.ValidateToken += (e, s) =>
    {
        if (char.IsUpper(s.Token.ValueString[0]) == false)
        {
            s.RejectToken();
        }    
    };
    

    Thank you Roman Ivantsov (Original Creator) for responding and helping me with this via email.