JavaCC: как обращаться с токенами, которые содержат общие слова
Я пытаюсь создать парсер для исходного кода следующим образом:
[code table 1.0]
code table code_table_name
id = 500
desc = "my code table one"
end code table
... и здесь ниже грамматика, которую я определил:
PARSER_BEGIN(CodeTableParser)
...
PARSER_END(CodeTableParser)
/* skip spaces */
SKIP: {
" "
| "\t"
| "\r"
| "\n"
}
/* reserved words */
TOKEN [IGNORE_CASE]: {
<CODE_TAB_HEADER: "[code table 1.0]">
| <CODE_TAB_END: "end" (" ")+ <CODE_TAB_BEGIN>>
| <CODE_TAB_BEGIN: <IDENT> | "code" (" ")+ "table">
| <ID: "id">
| <DESC: "desc">
}
/* token images */
TOKEN: {
<NUMBER: (<DIGIT>)+>
| <IDENT: (<ALPHA>)+>
| <VALUE: (<ALPHA> ["[", "]"])+>
| <STRING: <QUOTED>>
}
TOKEN: {
<#ALPHA: ["A"-"Z", "a"-"z", "0"-"9", "$", "_", "."]>
| <#DIGIT: ["0"-"9"]>
| <#QUOTED: "\"" (~["\""])* "\"">
}
void parse():
{
}
{
expression() <EOF>
}
void expression():
{
Token tCodeTab;
}
{
<CODE_TAB_HEADER>
<CODE_TAB_BEGIN>
tCodeTab = <IDENT>
(
<ID>
<DESC>
)*
<CODE_TAB_END>
}
Проблема в том, что синтаксический анализатор правильно идентифицирует токен ("таблица кодов")... но он не идентифицирует токен IDENT ("code_table_name"), поскольку он содержит слова, уже содержащиеся в токене CODE_TAB_BEGIN (то есть "код"). Парсер жалуется, говоря, что "за кодом следует неверный символ _"...
Сказав это, я задаюсь вопросом, чего мне не хватает, чтобы синтаксический анализатор работал правильно. Я новичок, и любая помощь будет очень признательна;-)
Спасибо, j3d
1 ответ
Ваш лексер никогда не будет выдавать IDENT, потому что производство
<CODE_TAB_BEGIN: <IDENT> | "code" (" ")+ "table">
говорит, что каждый IDENT может быть CODE_TAB_BEGIN и, так как это производство на первом месте, он превосходит производство для IDENT по первому правилу соответствия. (RTFFAQ)
Заменить это производство на
<CODE_TAB_BEGIN: "code" (" ")+ "table">
У вас возникнут проблемы с ID и DESC, но это поможет вам преодолеть вторую строку ввода.