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
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.