我正在为生产环境构建自定义表达式解析器和评估程序,以便为用户提供有限的DSL。解析器本身就像DSL一样,需要简单。解析器将使用不支持动态表达式解析的外来语言构建,也不提供任何解析器生成器工具。
我目前的决定是使用LL(1)语法进行递归下降法,因此即使没有评估表达式经验的程序员也可以快速了解代码的工作原理。
它必须处理由多种数据类型组成的混合表达式:小数,百分比,字符串和日期。 dd / mm / yyyy格式的日期很容易与一系列除法运算混淆。
这是解决这个问题的好方法吗?
我自己的解决方案旨在保持解析器简单,并使用特殊符号为日期添加前缀,让我们说撇号:
<date> ::= <apostr><digit><digit>/<digit><digit>/<digit><digit><digit><digit>
<apostr> ::= '
<digit> ::= '0'..'9'
答案 0 :(得分:2)
首先,我是LL解析器的粉丝,所以我衷心赞同你的方法。请注意,其中一个较新的流行解析器生成器(ANTLR)是LL。如果你允许更多的前瞻,而不是限制你自己LL(1),你可以做任何你想用LR(1)解析器做的事情,但代码将更清晰,更可靠,并且更容易调试。
我对你的整体语法知之甚少。您可以设计一些东西,以便LL解析器始终可以从上下文中判断它是整数表达式还是日期常量。但是,假设你不能,是的,你需要某种方式来区分它们。我能想到的另一件事就是使用反斜杠作为分隔符而不是斜杠,但这有点难看。
答案 1 :(得分:2)
具有无限前瞻性的类似LL的无法解析器是您所需要的。而且,它是PEG。
http://en.wikipedia.org/wiki/Parsing_expression_grammar
通过有序选择,很容易避免这个日期与常数文字分歧混淆。
答案 2 :(得分:0)
当一种语言用于人类输入时,定义它就是
的问题满足第二个要求比第一个要求困难得多,需要深入了解
基本上,如果没有很好地掌握预期用途和用户,很难就语言语法提出建议 不过,我想就日期格式问题提出以下建议:
完全使用日期值的替代格式;一个对用户来说足够“自然”但又足够独特,常规语法可以描述的一个
例如,一个使用月份的3个字母缩写的(下行DSL与英语或其他语言相关联,但也有优势,人类的模糊性是哪一天,哪个月是删除) 。姑且:
dd-mmm-yyyy (may seem unnatural in cultures where the prevailing date order
starts with the month maybe yyyy-mmm-dd then ?)
mmm-dd-yyyy (better for the above mentioned cultures)
ddmmmyyyy (avoid the dashes, but impose leading zeros)
MnnDnnYyyyy (using "M", "D" and "Y" (or others) as explicit prefixes; now,
this is completely culture neutral, but maybe a bit awkward...)
无论如何,只是想法......适用性将随着提及的人/文化因素而变化,和与其余语法不同。例如,上述内容可能意味着明确标记变量(这是许多语言使用$前缀的原因之一),以避免与[奇数但可能]变量标识符发生冲突。
简而言之,我们的想法是替换对特殊字符前缀的需要(然后可能会与使用这些字符的数学和其他表达式相冲突),使12个月标记成为解析器的足够好的鉴别器。 / p>