2015-04-11 7 views
0

Вот мой маркер таблицы:Неуверенный, почему этот LOOKAHEAD необходим в этих контекстах

TOKEN : 
{ 
    < A : "A" > 
| < B : "B" > 
| < C : "C" > 
} 

У меня есть этот код, который содержит 2 выбора конфликтов.

void Start() : {} { 
    < A> [ Bs() ] "-" < A> 
} 
void Bs() : {} { 
    ("-" < B>)+ 
} 

Для того, чтобы удалить конфликты выбор предупреждения, мне нужно добавить 2 LOOKAHEAD заявления, как так ...

void Start() : {} { 
    < A> [ LOOKAHEAD(2) Bs() ] "-" < A> 
} 
void Bs() : {} { 
    (LOOKAHEAD(1) "-" < B>)+ 
} 

Я понимаю, почему первый LOOKAHEAD (2) нужен, но у меня нет идея, почему нужен второй LOOKAHEAD (1). Может кто-нибудь объяснить?

Аналогично для этого примера ...

void Start() :{} { 
    one() 
    | 
    two() 
    | 
    three() 
    | 
    four() 
} 
void one() : {} { 
    [ <B> ] (<A>)* <C> 
} 
void two() : {} { 
    <B> <A> < A> <B> 
} 
void three() : {} { 
    <B> <B> <A> [ <B> ] <A> 
} 
void four() : {} { 
    <A> [ <B><C> ] two() 
} 

Для того, чтобы удалить конфликты выбора, мне нужно добавить LOOKAHEADS как так ...

void Start() :{} { 
    LOOKAHEAD(1) one() 
    | 
    LOOKAHEAD(1) two() 
    | 
    three() 
    | 
    four() 
} 
void one() : {} { 
    [ <B> ] (<A>)* <C> 
} 
void two() : {} { 
    <B> <A> < A> <B> 
} 
void three() : {} { 
    <B> <B> <A> [ <B> ] <A> 
} 
void four() : {} { 
    <A> [ LOOKAHEAD(1) <B><C> ] two() 
} 

Я понятия не имею, почему эти LOOKAHEADS удалите предупреждения. Любое понимание помощи будет оценено по достоинству.

ответ

2

Для вашего первого примера, из-за того, как вы определили Start, Bs может последовать за "-" токеном. Теперь скажем, что вход A - B - .... Должен ли цикл ("-" < B>)+ выполняться один или два раза? Это зависит от следующего элемента ввода. Если это A, один раз, если это B, по крайней мере дважды. Поэтому парсеру нужно смотреть мимо «-».

Для вашего второго примера: JavaCC не дает предупреждений, когда вы вводите спецификации LOOKAHEAD, даже если спецификации LOOKAHEAD недостаточны для решения проблемы. В этом случае вы можете использовать

void Start() :{} { 
    LOOKAHEAD([ <B> ] (<A>)* <C>) one() 
    | 
    LOOKAHEAD(<B> <A>) two() 
    | 
    three() 
    | 
    four() 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^