XML的forms语法

我试图在C中为XML文件构建小解析器。我知道,我可以找到一些完成的解决方案但是,我只需要一些基本的东西用于嵌入式项目。 我试图创建语法来描述没有属性的XML,只是标签,但似乎它不起作用,我无法弄清楚原因。

这是语法:

XML : FIRST_TAG NIZ NIZ : VAL NIZ | eps VAL : START VAL END | STR | eps 

以下是实现此语法的C代码的一部分:

 void check() { getSymbol(); if( sym == FIRST_LINE ) { niz(); } else { printf("FIRST_LINE EXPECTED"); exit(1); } } void niz() { getSymbol(); if( sym == ERROR ) return; if( sym == START ) { back = 1; val(); niz(); } printf(" EPS OR START EXPECTED\n"); } void val() { getSymbol(); if( sym == ERROR ) return; if( sym == START ) { back = 0; val(); getSymbol(); if( sym != END ) { printf("END EXPECTED"); exit(1); } return; } if( sym == EMPTY_TAG || sym == STR) return; printf("START, STR, EMPTY_TAG OR EPS EXPECTED\n"); exit(1); 

}

  void getSymbol() { int pom; if(back == 1) { back = 0; return; } sym = getNextToken(cmd + offset, &pom); offset += pom + 1; } 

编辑:以下是不满足此语法的XML文件示例:

   15/08/2012 1452 01KE000001 1 A 16.00 18.00 B 2.00 0.00 C 5.00 0.00 25/05/2010 2 C 0.00 4.00  

它在输出端给出了END EXPECTED。

首先,你的语法需要一些工作。 假设正确处理了前导码,则在NIZ的定义中存在基本错误。

 NIZ : VAL NIZ | eps VAL : START VAL END | STR | eps 

所以我们输入NIZ,我们首先寻找VAL。 问题是VAL的可能产品 NIZ结束时的eps。 因此,如果VAL不产生任何东西(即eps)并且在该过程中不消耗令牌(它不能正确,因为eps是生产),NIZ减少到:

 NIZ: eps NIZ | eps 

这不好。

考虑一下这些方面的更多内容:我只是在没有真正的远见的情况下对此进行了研究,以获得超越纯粹基本结构的东西。

 XML: START_LINE ELEMENT ELEMENT: OPENTAG BODY CLOSETAG OPENTAG: lt id(n) gt CLOSETAG: lt fs id(n) gt BODY: ELEMENT | VALUE VALUE: str | eps 

这是超级基础。 终端包括:

 lt: '<' gt: '>' fs: '/' str: any alphanumeric string excluding chars lt or gt. id(n): any alphanumeric string excluding chars lt, gt, or fs. 

我几乎可以感觉到XML纯粹主义者现在对我的愤怒,但我想要了解的一点是,当语法定义明确时,RDP会自己写出来。 显然,词法分析器(即令牌引擎)需要相应地处理终端。 注意:id(n)是一个id-stack,用于确保正确关闭最内层标记,并且是解析器根据其管理标记ID的方式的属性。 它不是传统的,但它使事情变得更加容易。

这可以/应该清楚地扩展到包括独立元素声明和快捷元素闭包。 例如,这个语法允许这种forms的元素:

 ... 

但不是这种forms:

  

它也不代表捷径终止,例如:

 ... 

考虑到这样的添加显然会使语法复杂化,但也使解析器更加健壮。 就像我说的那样,上面的例子是基本的,有一个大写字母B.如果你真的要开始这个,那么你在设计语法时要考虑的事情,以及后果也是你的RDP。

无论如何,只要考虑一下你的语法中的一些reworks可以/将如何使你更容易。