#types #antlr
#типы #antlr
Вопрос:
Я пишу грамматику JavaScript, которая включает в себя больше типов, таких как float, int, boolean и т.д. когда я печатаю, чтобы получить информацию из хэш-карты, используя идентификатор (букву или слова) в качестве ключа, моя программа всегда будет переходить к первому идентификатору, и это вызовет большую проблему, кто-нибудь знает, как я могу ее решить?
Например:
bool returns [boolean value]
: ID {$value = hashmap.get($ID.text);}
;
float returns [float value]
: ID {$value = hashmap.get($ID.text);}
;
Поскольку я использую ID для получения возврата как для bool, так и для float, он всегда будет сначала переходить к bool и запускать часть bool вместо части float, даже если ID хранит число с плавающей запятой.
Ответ №1:
Когда вы говорите, что «моя программа всегда будет переходить к первому идентификатору», я предполагаю, что вы имеете в виду, что где-то еще в вашей грамматике у вас есть правило, подобное этому:
expr: ...
| bool
| float
;
И что это всегда будет учитываться в bool
правиле, потому что оно стоит первым и соответствует тем же токенам, что и float
. Обычно нет смысла иметь две альтернативы в правиле, которые оба расширяются до одних и тех же токенов.
Вы могли бы создать соответствие bool
и float
только в том случае, ID
если оно содержится в соответствующей карте, используя предикаты, но это, как правило, не очень хорошая идея. Гораздо более распространенным подходом является создание единой карты, содержащей записи для всех переменных независимо от их типа.
PS: В более общем плане, похоже, что вы пытаетесь вычислять выражения непосредственно в анализаторе (по крайней мере, название возвращаемого вами значения предполагает, что вы пытаетесь вычислить значение выражения). Обратите внимание, что этот подход не будет работать дальше простого калькулятора. Как только вы введете какой-либо поток управления (вызовы функций, операторы if, циклы), вы обнаружите, что невозможно контролировать, когда и как часто должен выполняться код в действиях (он всегда будет выполняться ровно один раз при разборе данного кода). Вместо того, чтобы делать это таким образом, ваш анализатор должен просто создать дерево или байт-код, который затем вы можете выполнить на отдельном шаге.