Xtext/ANTLR:如何修复此错误?以下令牌定义在…之前永远无法匹配。。。?
我制作了一个语法,编辑器没有显示任何错误,当我选择“生成XText工件”时,我得到以下错误: 错误(208):../mestra.dmxlightshow/src gen/mestra/parser/antlr/internal/InternalDmxLightShow.g:3668:1:无法匹配以下令牌定义,因为先前的令牌与相同的输入匹配:RULE_MIDI_CHANNEL 错误(208):../mestra.dmxlightshow.ide/src gen/mestra/ide/contentassist/antlr/internal/internal dmxlightshow.g:10741:1:无法匹配以下令牌定义,因为先前的令牌匹配相同的输入:RULE\u MIDI\u CHANNEL MIDI_通道/MIDI通道仅用于以下片段:Xtext/ANTLR:如何修复此错误?以下令牌定义在…之前永远无法匹配。。。?,antlr,grammar,dsl,xtext,model-driven-development,Antlr,Grammar,Dsl,Xtext,Model Driven Development,我制作了一个语法,编辑器没有显示任何错误,当我选择“生成XText工件”时,我得到以下错误: 错误(208):../mestra.dmxlightshow/src gen/mestra/parser/antlr/internal/InternalDmxLightShow.g:3668:1:无法匹配以下令牌定义,因为先前的令牌与相同的输入匹配:RULE_MIDI_CHANNEL 错误(208):../mestra.dmxlightshow.ide/src gen/mestra/ide/conten
MidiNoteTrigger:
'Note' onOff=ON_OFF 'Channel' mc=MidiChannel ('Note' note=MidiNote | 'NoteRange' noteRange=MidiNoteRange) velocity=MIDI_VALUE;
MidiCcTrigger:
'CC' 'Channel' mc=MidiChannel 'Number' ccNumber=(MIDI_VALUE) ('Value' value=MidiValue | 'ValueRange' valueRange=MidiValueRange);
MidiAftertouchTrigger:
'Aftertouch' 'Channel' mc=MidiChannel ('Value' value=MidiValue | 'ValueRange' valueRange=MidiValueRange);
MidiProgramChangeTrigger:
'PrgChg' 'Channel' mc=MidiChannel 'Bank' bank=MidiValue 'Program' program=MidiValue;
MidiChannel:
channel=('OMNI' | MIDI_CHANNEL);
在每个规则的开头(除了MidiChannel’有一个关键字('Time','Note','CC','Aftertouch','PrgCh',所以我希望下面的规则都是唯一的
MIDI_通道的定义为:
terminal MIDI_CHANNEL:
('1' '0'..'6') |
( '0'..'9');
如何修复此错误
完整语法如下:
我做的测试
// Grammar
grammar mestra.DmxLightShow with org.eclipse.xtext.common.Terminals
generate dmxLightShow 'http://www.DmxLightShow.mestra'
// Main structure
Mestra:
'songs:' songs +=Song+
'triggers:' triggers+=RuleTrigger+
'commands:' commands+=Command+;
// Song structure
Song:
'song' name=ID ':'
'bank' bank=MIDI_VALUE 'program' program=MIDI_VALUE ';'
rules=Rules
('order' sequenceRefs+=[Sequence] (',' sequenceRefs+=[Sequence])* ';'
'sequences:' sequences += Sequence+)?;
Sequence:
'sequence' name=ID ':'
rules=Rules
('order' stepRefs+=[Step] (',' stepRefs+=[Step])* ';'
'steps:' steps += Step+)?;
Step:
'step' name=ID ':'
rules=Rules;
// Rules
Rules:
{Rules} rules+=Rule*;
Rule:
'rule' (ruleTriggers=RuleTriggers ':')? ruleCommands=RuleCommands ';';
RuleTriggers:
triggerRefs+=[RuleTrigger] (',' triggerRefs+=[RuleTrigger])*;
RuleCommands:
commandsRefs+=[Command] (',' commandsRefs+=[Command])*;
// Rule Triggers
RuleTrigger:
name=ID type=(/* DmxRuleTrigger | */ MidiRuleTrigger) ';';
// DmxRuleTrigger: // Not supported
MidiRuleTrigger:
type=(MidiTimeTrigger | MidiNoteTrigger | MidiCcTrigger | MidiAftertouchTrigger | MidiProgramChangeTrigger) ';';
MidiTimeTrigger:
'Time' time=Time;
MidiNoteTrigger:
'Note' onOff=ON_OFF 'Channel' mc=MidiChannel ('Note' note=MidiNote | 'NoteRange' noteRange=MidiNoteRange) velocity=MIDI_VALUE;
MidiCcTrigger:
'CC' 'Channel' mc=MidiChannel 'Number' ccNumber=(MIDI_VALUE) ('Value' value=MidiValue | 'ValueRange' valueRange=MidiValueRange);
MidiAftertouchTrigger:
'Aftertouch' 'Channel' mc=MidiChannel ('Value' value=MidiValue | 'ValueRange' valueRange=MidiValueRange);
MidiProgramChangeTrigger:
'PrgChg' 'Channel' mc=MidiChannel 'Bank' bank=MidiValue 'Program' program=MidiValue;
MidiChannel:
channel=('OMNI' | MIDI_CHANNEL);
MidiValue:
value=MIDI_VALUE;
MidiValueRange:
start=MIDI_VALUE '-' end=MIDI_VALUE;
MidiNote:
'Note' note=MIDI_NOTE;
MidiNoteRange:
'NoteRange' start=MIDI_NOTE '-' end=MIDI_NOTE;
Time:
'Time' time=INT type=('ms' | 's' );
// Commands
Command:
name=ID type=(DmxCommand /* | MidiCommand */ ) ';';
// MidiCommand: // Not supported
DmxCommand:
parGroup=ParGroup dmxSubCommands=DmxSubCommands ';';
ParGroup:
(parGroup= 'AllGroupsAll' |
{ParGroup} 'AllGroupsCenter' |
{ParGroup} 'AllGroupsAllExceptEgoRisers' |
{ParGroup} 'AllGroupsLeft' |
{ParGroup} 'AllGroupsRight' |
{ParGroup} 'LedBarAll' |
{ParGroup} 'LedBarCenter' |
{ParGroup} 'LedBarLeft' |
{ParGroup} 'LedBarRight' |
{ParGroup} 'DrumsAll' |
{ParGroup} 'DrumsLeft' |
{ParGroup} 'DrumsRight' |
{ParGroup} 'EgoRisersAll' |
{ParGroup} 'EgoRisersLeft' |
{ParGroup} 'EgoRisersRight' |
{ParGroup} 'FrontAll' |
{ParGroup} 'FontCorners' |
{ParGroup} 'FrontMiddle' |
{ParGroup} 'FrontInner' |
{ParGroup} 'FrontOuter' |
{ParGroup} 'FrontLeft1Inside' |
{ParGroup} 'FrontLeft2' |
{ParGroup} 'FrontLeft3' |
{ParGroup} 'FrontLeft4Outside' |
{ParGroup} 'FrontLeftAll' |
{ParGroup} 'FrontLeftInner' |
{ParGroup} 'FrontLeftOuter' |
{ParGroup} 'BannerAll' |
{ParGroup} 'BannerLeft' |
{ParGroup} 'BannerRight' |
{ParGroup} 'FrontRight1Inside' |
{ParGroup} 'FrontRight2' |
{ParGroup} 'FrontRight3' |
{ParGroup} 'FrontRight4Outside' |
{ParGroup} 'FrontRightAll' |
{ParGroup} 'FrontRightInner' |
{ParGroup} 'FrontRightOuter');
DmxSubCommands:
{DmxSubCommands}
(mode=DmxModeSubCommand)?
(preset=DmxPresetSubCommand)?
(delayTime=DmxDelayTimeSubCommand)?
(strobeTime=DmxStrobeTimeSubCommand)?
(stepNumber=DmxStepNumberSubCommand)?
(hold=DmxHoldSubCommand)?
(once=DmxOnceSubCommand)?
(DefaultColor=DmxDefaultColorSubCommand)?
(AlternateColor=DmxAlternateColorSubCommand)?;
DmxModeSubCommand:
'Mode' DmxModeSubCommandData;
DmxModeSubCommandData:
type=('trigger' | 'loop' | 'once' | 'restart');
DmxPresetSubCommand:
'Preset' DmxPresetSubCommandData;
DmxPresetSubCommandData:
presetName= 'def2alt' |
{DmxPresetSubCommandData} 'alt2def' |
{DmxPresetSubCommandData} 'switch_def_alt' |
{DmxPresetSubCommandData} 'def2act' |
{DmxPresetSubCommandData} 'actual2def' |
{DmxPresetSubCommandData} 'switch_def_actual' |
{DmxPresetSubCommandData} 'alt2actual' |
{DmxPresetSubCommandData} 'actual2alt' |
{DmxPresetSubCommandData} 'switch_alt_actual' |
{DmxPresetSubCommandData} 'solid' |
{DmxPresetSubCommandData} 'dual_colors_def_alt' |
{DmxPresetSubCommandData} 'dual_colors_alt_def' |
{DmxPresetSubCommandData} 'chase_left2right' |
{DmxPresetSubCommandData} 'chase_right2left' |
{DmxPresetSubCommandData} 'switch_left_right_left' |
{DmxPresetSubCommandData} 'switch_right_left_right' |
{DmxPresetSubCommandData} 'fade_alt2def' |
{DmxPresetSubCommandData} 'fade_def2alt' |
{DmxPresetSubCommandData} 'fade_def_alt_def' |
{DmxPresetSubCommandData} 'fade_alt_def_alt' |
{DmxPresetSubCommandData} 'fade_chase_left2right' |
{DmxPresetSubCommandData} 'fade_chase_right2left' |
{DmxPresetSubCommandData} 'fade_chase_left_right_left' |
{DmxPresetSubCommandData} 'fade_chase_right_left_right' |
{DmxPresetSubCommandData} 'rainbow_no_fade_left2right' |
{DmxPresetSubCommandData} 'rainbow_no_fade_right2left' |
{DmxPresetSubCommandData} 'rainbow_fade_left2right' |
{DmxPresetSubCommandData} 'rainbow_fade_right2left';
DmxDelayTimeSubCommand:
'DelayTime' time=Time;
DmxStrobeTimeSubCommand:
'StrobeTime' time=Time;
DmxStepNumberSubCommand:
'StepNumber' (last='Last' | value=INT);
DmxHoldSubCommand:
'Hold' onOff=ON_OFF;
DmxOnceSubCommand:
'Once' onOff=ON_OFF;
DmxDefaultColorSubCommand:
'DefaultColor' color=DmxColor;
DmxAlternateColorSubCommand:
'AlternateColor' color=DmxColor;
DmxColor:
ShortDmxColor | LongDmxColor;
ShortDmxColor:
{ShortDmxColor} (intensity='I')? (red='R')? (green='G')? (blue='B')? (white='W')?;
LongDmxColor:
intensity=DMX_VALUE red=DMX_VALUE green=DMX_VALUE blue=DMX_VALUE (white=DMX_VALUE)?;
// Terminals
terminal MIDI_VALUE:
('1' '2' '0'..'7') |
('1' '0'..'1' '0'..'9') |
( '1'..'9' '0'..'9') |
( '0'..'9');
terminal DMX_VALUE:
('2' '5' '0'..'5') |
('2' '0'..'4' '0'..'9') |
('1' '0'..'9' '0'..'9') |
( '1'..'9' '0'..'9') |
( '0'..'9');
terminal MIDI_CHANNEL:
('1' '0'..'6') |
( '0'..'9');
terminal MIDI_NOTE:
('C' | 'D' | 'E' | 'F' | 'G' | 'A' | 'B')
('b' | '#')
('0'..'9') | ('1' '0'..'1');
terminal ON_OFF:
('ON' | 'OFF');
规则
MIDI\u值
和DMX\u值
和MIDI\u通道
相互重叠
可能的解决办法
INT
+验证器(适用于所有验证器)MIDI\u通道:INT
(无终端关键字)+值转换器MIDI_通道:TERMINAL1 | TERMINAL2 |..
啊,这似乎与我的另一个问题非常相关……我会检查(当我有时间时,明天或周五)