【问题标题】:Irony Parsing a list delimited with white space具有讽刺意味的是,解析以空格分隔的列表
【发布时间】:2020-02-12 13:27:59
【问题描述】:

我正在尝试为 Allen Bradly SLC 语言/文件格式编写解析器。我已经成功地让它解析了一个寄存器引用。 IE。 N5:4/3。但是,当我尝试进入下一个级别时,让它解析由空格分隔的寄存器引用列表,它会引发以下错误

输入:

N30:3/8 B20:3/3

错误:

(L1, C9) 语法错误,预期::

这是我的代码,可以构建并将 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);

我明白了

错误:(L1,C9)语法错误,预期:

我认为这意味着它需要一个空格字符

任何帮助将不胜感激。我刚刚开始学习讽刺,没有大量的文档。

注意:稍后我希望能够解析一个采用T8:5/DN 形式的寄存器,这意味着在正斜杠之后是一个字符串而不是一个数字。被终止的是空白

【问题讨论】:

    标签: c# bnf irony


    【解决方案1】:

    使用 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(原始创建者)通过电子邮件回复并帮助我解决此问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-11-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-20
      • 1970-01-01
      相关资源
      最近更新 更多