我是ANTLR的初学者,我需要修改现有的 - 复杂的 - 语法。
我想创建一个规则来保留一个块而不用其他规则解析。 为了更清楚,我需要将用c ++编写的代码插入到解释代码中。
编辑11/02/2013
经过多次测试,这是我的语法,测试,结果,结果和需求:
cppLiteral
: cppBegin cppInnerTerm cppEnd
;
cppBegin
: '//$CPP_IN$'
;
cppEnd
: '//$CPP_OUT$'
;
cppInnerTerm
: ( ~('//$CPP_OUT$') )*
;
//$CPP_IN$
txt1 txt2
//$CPP_OUT$
cppLiteral ->
cppBegin = '//$CPP_IN$'
cppInnerTerm = 'txt1' 'txt2'
cppEnd = '//$CPP_OUT$'
cppLiteral ->
cppBegin = '//$CPP_IN$'
cppInnerTerm = 'txt1 txt2'
cppEnd = '//$CPP_OUT$'
(抱歉,我无法发布AST的图像,因为我没有10个声誉)
三个标记“cppBegin”,“cppInnerTerm”和“cppEnd”可以在一个标记中,如下所示:
cppLiteral
: '//$CPP_IN$'( ~('//$CPP_OUT$') )*'//$CPP_OUT$'
;
得到这个结果:
cppLiteral = '//$CPP_IN$\n txt1 txt2\n //$CPP_OUT$'
答案 0 :(得分:0)
我想创建一个规则来保留一个块而不用其他规则解析。
将其解析为多行注释,例如: /* foobar */
。以下是使用问题中指定的关键字的小示例。
请注意,大多数工作都是使用词法规则(以大写字母开头的规则)完成的。任何时候你想处理文本块,特别是如果你想避免在这种情况下的其他规则,你可能会考虑词法规则而不是解析器规则。
grammar CppBlock;
document: CPP_LITERAL* EOF;
fragment CPP_IN:'//$CPP_IN$';
fragment CPP_OUT:'//$CPP_OUT$';
CPP_LITERAL: CPP_IN .* CPP_OUT
{
String t = getText();
t = t.substring(10, t.length() - 11); //10 = length of CPP_IN, 11 = length of CPP_OUT
setText(t);
}
;
WS: (' '|'\t'|'\f'|'\r'|'\n')+ {skip();};
这是一个简单的测试用例:
<强>输入强>
//$CPP_IN$
static const int x = 0; //magic number
int *y; //$CPP_IN$ <-- junk comment
static void foo(); //forward decl...
//$CPP_OUT$
//$CPP_IN$
//Here is another block of CPP code...
const char* msg = ":D";
//The end.
//$CPP_OUT$
输出代币
[CPP_LITERAL :
static const int x = 0; //magic number
int *y; //$CPP_IN$ <-- junk comment
static void foo(); //forward decl...
]
[CPP_LITERAL :
//Here is another block of CPP code...
const char* msg = ":D";
//The end.
]
规则CPP_LITERAL
会在输入的开头和结尾(//$CPP_IN$
之后和//$CPP_OUT$
之前)保留换行符。如果您不想要这些,只需更新操作即可将其删除。否则,我认为这个语法符合你的要求。