[[1] * 4] * 3
или даже:
[[1, 1, 1, 1]] * 3
Создает список, который ссылается на внутренний [1,1,1,1]
3 раза - не три копии внутреннего списка, поэтому в любое время, когда вы изменяете список (в любом позиция), вы увидите изменение три раза.
Это то же самое, что и в этом примере:
>>> inner = [1,1,1,1]
>>> outer = [inner]*3
>>> outer
[[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]]
>>> inner[0] = 5
>>> outer
[[5, 1, 1, 1], [5, 1, 1, 1], [5, 1, 1, 1]]
, где это, вероятно, немного менее удивительно.
Строка "keyup"
помечена как токен NAME
: это проблема.
Вы должны понимать, что лексер работает независимо от анализатора. Если синтаксический анализатор пытается сопоставить токен KEYPRESS
, лексер не «слушает» его, а просто строит токен, следуя правилам:
Принимая во внимание эти правила и порядок ваших правил :
NAME : [A-Za-z_][A-Za-z_0-9]* ;
INT : [0-9]+ ;
KEY : [a-z] | [0-9] | 'shift' | 'ctrl' | 'alt' | 'meta' | 'space' | 'left' | 'right' | 'up' | 'down' | 'minus' | 'equals' | 'backspace' | 'openbracket' | 'closebracket' | 'backslash' | 'semicolon' | 'quote' | 'enter' | 'comma' | 'period' | 'slash' ;
KEYPRESS : 'keyup' | 'keydown' ;
маркер NAME
будет создан до большей части альтернатив KEY
, и все альтернативы KEYPRESS
будут созданы.
И поскольку INT
соответствует одной или нескольким цифрам и определен до KEY
, который также имеет альтернативу с одной цифрой, ясно, что лексер никогда не будет генерировать KEY
или KEYPRESS
токен.
Если вы переместите правило NAME
и INT
ниже правил KEY
и KEYPRESS
, то большинство токенов будут построены так, как вы ожидаете, это мое предположение.
Возможное решение будет выглядеть так:
KEY : [a-z] | 'shift' | 'ctrl' | 'alt' | 'meta' | 'space' | 'left' | 'right' | 'up' | 'down' | 'minus' | 'equals' | 'backspace' | 'openbracket' | 'closebracket' | 'backslash' | 'semicolon' | 'quote' | 'enter' | 'comma' | 'period' | 'slash' ;
KEYPRESS : 'keyup' | 'keydown' ;
NAME : [A-Za-z_][A-Za-z_0-9]* ;
SINGLE_DIGIT : [0-9] ;
INT : [0-9]+ ;
Т.е. Я удалил альтернативу [0-9]
из KEY
и ввел правило SINGLE_DIGIT
(которое помещено перед правилом INT
!).
Теперь создайте дополнительный парсер rules:
integer : INT | SINGLE_DIGIT ;
key : KEY | SINGLE_DIGIT ;
и изменить все вхождения INT
внутри правил синтаксического анализа на integer
(не вызывать ваше правило int
: это зарезервированное слово) и изменить все KEY
к key
.
И вы также можете сделать что-то похожее на NAME
и альтернативу [a-z]
в KEY
(т. е. один символ нижнего регистра теперь никогда не будет обозначаться как NAME
], всегда как KEY
).
leftFlipper name=a x=16 y=2 orientation=0
, выдает ошибку, потому что теперь имя соответствует KEY, пока оно не соответствует NAME. – tripatheea 13 May 2014 в 20:40INT
, а какKEY
. – Bart Kiers 13 May 2014 в 20:41