具有讽刺意味的是,正在解析以白色分隔的列表 space
Irony Parsing a list delimited with white space
我正在尝试为 Allen Bradly SLC Language/File 格式编写解析器。我已经成功地让它解析了一个寄存器引用。 IE。 N5:4/3。但是,当我尝试进入下一个级别时,让它解析由 whitespace 分隔的寄存器引用列表,它会抛出以下错误
输入:
N30:3/8 B20:3/3
错误:
(L1, C9) Syntax error, expected: :
这是我的代码,可以构建它并将 dll 加载到 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
如果我更改以下行
SLCInstructionRegisterList.Rule = MakePlusRule(SLCInstructionRegisterList, SLCRegisterReference);
到
SLCInstructionRegisterList.Rule = MakePlusRule(SLCInstructionRegisterList, ToTerm(" "), SLCRegisterReference);
我明白了
Error: (L1,C9) Syntax error, expected:
我认为这意味着它需要一个 space 字符
如有任何帮助,我们将不胜感激。我刚刚开始学习讽刺,没有大量的文档。
注意:稍后我希望能够解析采用这种形式的寄存器 T8:5/DN
,这意味着在正斜杠之后是一个字符串而不是一个数字。终止的是白色 space
使用 ValidateTokenMethod 并拒绝任何不是 A-Z 的内容解决了这个问题。
问题是 / 被解释为新寄存器引用的开始
var SLCFilePrefix = new FixedLengthLiteral("Type", 1, TypeCode.String);
SLCFilePrefix.ValidateToken += (e, s) =>
{
if (char.IsUpper(s.Token.ValueString[0]) == false)
{
s.RejectToken();
}
};
感谢 Roman Ivantsov(原创者)通过电子邮件回复和帮助我。
我正在尝试为 Allen Bradly SLC Language/File 格式编写解析器。我已经成功地让它解析了一个寄存器引用。 IE。 N5:4/3。但是,当我尝试进入下一个级别时,让它解析由 whitespace 分隔的寄存器引用列表,它会抛出以下错误
输入:
N30:3/8 B20:3/3
错误:
(L1, C9) Syntax error, expected: :
这是我的代码,可以构建它并将 dll 加载到 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
如果我更改以下行
SLCInstructionRegisterList.Rule = MakePlusRule(SLCInstructionRegisterList, SLCRegisterReference);
到
SLCInstructionRegisterList.Rule = MakePlusRule(SLCInstructionRegisterList, ToTerm(" "), SLCRegisterReference);
我明白了
Error: (L1,C9) Syntax error, expected:
我认为这意味着它需要一个 space 字符
如有任何帮助,我们将不胜感激。我刚刚开始学习讽刺,没有大量的文档。
注意:稍后我希望能够解析采用这种形式的寄存器 T8:5/DN
,这意味着在正斜杠之后是一个字符串而不是一个数字。终止的是白色 space
使用 ValidateTokenMethod 并拒绝任何不是 A-Z 的内容解决了这个问题。
问题是 / 被解释为新寄存器引用的开始
var SLCFilePrefix = new FixedLengthLiteral("Type", 1, TypeCode.String);
SLCFilePrefix.ValidateToken += (e, s) =>
{
if (char.IsUpper(s.Token.ValueString[0]) == false)
{
s.RejectToken();
}
};
感谢 Roman Ivantsov(原创者)通过电子邮件回复和帮助我。