2015-06-01 3 views
0

В проекте я работаю в ANTLR (v4), у меня есть правило, как это:ANTLR (v4) Правило не прилагая

Equal  : '::=' 

Identifier 
    : ('A'..'Z' | '_' | '0'..'9') ('a'..'z' | 'A'..'Z' | '_' | '0'..'9')* 
    ; 
Constant 
    : Identifier Equal Expression 
    ; 

И я даю это код, как: X ::= 1, и, вместо того, чтобы быть «константой», он выдается как три отдельных токена: Идентификатор, Равный и Идентификатор. Я не могу понять, что я делаю неправильно. Возможно, мне стоит вернуться к использованию библиотеки Parsec от Haskell. (Причина, по которой я прекратил использовать, это длинная история.)

+0

... или вы можете перейти к комбайну синтаксического анализатора Scala :) –

+1

Вы определяете 'Constant' как токен лексера. Чаще всего это определить как правило парсера (записать его в нижний регистр 'константа'). Кроме того, было бы интересно, как определяется выражение «Выражение»? И есть ли правило lexer для пробелов? – CoronA

ответ

1

Они 3 жетона, потому что у вас есть промежутки между ними. Когда вы сделаете X::=1, он окажется в виде единственного токена Constant.

Возможно, вы указали правило lexer, которое пропускает пробелы, но это заставит синтаксический анализатор никогда не видеть эти пробельные символы, а не лексер.

Ваше постоянное правило должно быть правилом анализатора, тогда у вас не будет проблем. Не имеет смысла создавать один одиночный токен. Так должно быть, должно быть, ваше правило Expression. Токены (правила lexer) являются основными строительными блоками вашего языка. Как атомы в химии. Правила парсера (правила нижнего обхода) используются для склеивания этих токенов.

+0

Как пропустить все пробелы в лексере и синтаксическом анализаторе? Прямо сейчас у меня есть правило, подобное этому: 'Space : ('' | '\ t' | '\ r' | '\ n' | '\ u000C') {skip(); } ; ' –

+0

Проверьте мой отредактированный ответ. –