我正试图为照明控制系统创建一个语法,并且在使用tree工具进行测试时,我取得了很好的进展,但是当我尝试在我的应用程序中实现它时,它似乎都崩溃了。
该语言的基本结构是Source Mask Command 。掩码是可选的,因此一个超级简单的示例输入可能如下所示:绕过掩码的治具1@ 50。the 1是源,@是命令,50是目标,在本例中是强度值。
我对这种类型的输入没有问题,但是当我尝试构建更复杂的源代码选择时,事情变得复杂起来。假设我想选择一个范围的固定装置,并从选择中删除一些,然后在后面添加更多的固定装置。
夹具1 Thru 50-25-30-35+ 40 > 45 @ 50
在现有的控制系统中,这是一个非常常见的语法,但我很困惑如何设计这个语法,从而使集成到我的应用程序中并不太痛苦。
用户也可以很容易地键入以下内容:
1 Thru 50-25-30-35+ 40 > 45 @ 50
因为没有提供sourceType (夹具),所以它的推断。
为了尝试处理上述情况,我写了以下几篇文章:
grammar LiteMic;
/*
* Parser Rules
*/
start : expression;
expression : source command destination
| source mask command destination
| command destination
| source command;
destination : sourceType number
| sourceType number sourceType number
| number;
command : COMMAND;
mask : SOURCETYPE;
operator : ADD #Add
| SUB #Subtract
;
plus : ADD;
minus : SUB;
source : singleSource (plus source)*
| rangeSource (plus source)*
;
singleSource : sourceType number #SourceWithType
| number #InferedSource
;
rangeSource : sourceRange (removeSource)*
;
sourceRange : singleSource '>' singleSource;
removeSource : '-' source;
sourceType : SOURCETYPE;
number : NUMBER;
compileUnit
: EOF
;
/*
* Lexer Rules
*/
SOURCETYPE : 'Cue'
| 'Playback'
| 'List'
| 'Intensity'
| 'Position'
| 'Colour'
| 'Beam'
| 'Effect'
| 'Group'
| 'Fixture'
;
COMMAND : '@'
| 'Record'
| 'Update'
| 'Copy'
| 'Move'
| 'Delete'
| 'Highlight'
| 'Full'
;
ADD : '+' ;
SUB : '-' ;
THRU : '>' ;
/* A number: can be an integer value, or a decimal value */
NUMBER : [0-9]+ ;
/* We're going to ignore all white space characters */
WS : [ \t\r\n]+ -> skip
;对grun gui运行命令会产生以下结果:

我已经取得了一定程度的成功,能够重写AddRangeSource的侦听器,因为我可以循环并添加正确的类型,但是当我尝试删除一个范围时,所有这些都会分崩离析。
1 >50-30> 35 @ 50
这会在删除与“addRangeSource”匹配的范围时产生问题。

我很肯定我错过了一些显而易见的东西,我一直在努力阅读我在亚马逊上买的那本书,但我的脑子里还没有弄清楚如何归档我想要的东西,我已经看了一个星期了。
为了更好地衡量,下面是一棵树,用于更高级的查询,与所选内容相比似乎还可以。

有人对我出了什么问题有什么建议吗?
干杯,迈克
发布于 2018-11-11 18:01:17
您可以通过稍微调整语法来解决这个问题:
rangeSource与sourceRangerangeSource合并: singleSource '>‘singleSource;
注意:此规则还与输入(如Beam 1 > Group 16__ )匹配,这可能是意外的,在这种情况下,您可以使用以下命令:
rangeSource : sourceType?=‘3’>数;source重命名为sourceList (不要忘记在expression规则中更改它):
表达式: sourceList命令目的地\ sourceList掩码命令目的地\命令目的地_命令_命令_source或rangeSource匹配的规则:
资料来源: singleSource x rangeSource;+和-放在同一级别(如addSource和removeSource):
addSource : plus源;removeSource :减号源;sourceList以接受addSource/removeSource的列表:
sourceList :源(addSource=removeSource)*;我尝试过这样做,即使是更高级的查询,解析也没有任何问题。
https://stackoverflow.com/questions/53106950
复制相似问题