我是ANTLR的新手,我正在尝试使用C语言目标(antler3C)编写一个简单的解析器.语法很简单,我想让每个规则返回一个值,例如:
number returns [long value]
:
( INT {$value = $INT.ivalue;}
| HEX {$value = $HEX.hvalue;}
)
;
HEX returns [long hvalue]
: '0' 'x' ('0'..'9'|'a'..'f'|'A'..'F')+ {$hvalue = strtol((char*)$text->chars,NULL,16);}
;
INT returns [long ivalue]
: '0'..'9'+ {$ivalue = strtol((char*)$text->chars,NULL,10);}
;
Run Code Online (Sandbox Code Playgroud)
每个规则收集它的子规则的返回值,直到最顶层的规则返回一个充满我的数据的漂亮结构.
据我所知,ANTLR允许词法分析器规则(令牌,例如'INT'和'HEX')返回值,就像解析器规则一样(例如'number').但是,生成的C代码将无法编译:
error C2228: left of '.ivalue' must have class/struct/union
error C2228: left of '.hvalue' must have class/struct/union
Run Code Online (Sandbox Code Playgroud)
我做了一些探讨,错误是有道理的 - 令牌最终成为通用的ANTLR3_COMMON_TOKEN_struct,它不允许返回值.所以也许C目标不支持这个功能.但就像我说的那样,我是新手,在我开始寻找另一种方法之前,我想确认一下我不能这样做.
所以问题是:'antler3C是否支持lexer规则的返回值,如果是,那么使用它们的正确方法是什么?
我有多个父母的C++课程; 每个父级定义一个具有通用名称但具有不同目的的函数:
class BaseA
{
virtual void myFunc(); // does some task
};
class BaseB
{
virtual void myFunc(); // does some other task
};
class Derived : public BaseA, public BaseB;
Run Code Online (Sandbox Code Playgroud)
如果就是这样,我就没有问题 - 我可以使用using语句解决它的歧义,我可以选择使用基类名称和范围解析运算符来调用哪一个.
不幸的是,派生类需要覆盖它们:
class Derived : public BaseA, public BaseB
{
virtual void BaseA::myFunc(); // Derived needs to change the way both tasks are done
virtual void BaseB::myFunc();
}
Run Code Online (Sandbox Code Playgroud)
这不起作用,不是因为它引入了新的歧义(虽然它可能),但是因为
"错误C3240:'myFunc':必须是'BaseA'的非重载抽象成员函数"
"错误C2838:成员声明中的非法限定名称"
在不同的情况下,我可能只是重命名方法,或者像编译器建议的那样使它们成为纯虚方法.但是,类层次结构和许多外部问题使得第一个选项非常困难,第二个选项不可能.
有没有人有建议?为什么限定符仅允许纯虚方法?有没有办法同时覆盖虚拟方法和解决歧义?