我目前正在开发一个将字符串(单个变量“ x”的函数)作为输入并输出该函数的派生类的应用程序。程序的后半部分目前不是问题,我唯一遇到的麻烦是从字符串“读取”函数。我正在使用C的ANTLRv3来尝试实现此目标,但是我似乎无法使其正常工作。目前,我缺少“ antlr3.h”头文件,该文件似乎在任何地方都找不到。我的第二个问题是调用生成的解析器,该解析器的C(++)代码是什么(ANTLR代码在下面发布)?我如何使它工作?
提前致谢,
领带
grammar Expression;
options {
language = C;
}
@header {
#ifndef PI
#define PI 3.1415926535897
#endif // PI
#ifndef E
#define E 2.7182818284590
#endif // E
#include "ExpressionTree.h"
#include <vector>
#include <cstdlib>}
parse returns [Functor* func]
: e=addExp EOF {func = $e.func;}
;
addExp returns [Functor* func]
@init {std::vector<Functor*> addList;
std::vector<bool> opList;}
: e1=multExp {addList.push_back($e1.func);} (o=('+'|'-') e2=multExp {opList.push_back($o.text == '+'); addList.push_back($e2.func);})*
{
if(addList.size() == 1) {
func = addList[0];
} else {
Functor* current = addList[0];
for(int i = 0; i<opList.size(); i++) {
if(opList[i]) {
current = new Plus(current, addList[i+1]);
} else {
current = new Minus(current, addList[i+1]);
}
}
func = current;
}};
multExp returns [Functor* func]
@init {
std::vector<Functor*> mulList;
std::vector<bool> opList;}
: e1=powExp {mulList.push_back($e1.func);} (o=('*'|'/') e2=powExp {opList.push_back($o.text == '*'); mulList.push_back($e2.func);})*
{
if(mulList.size() == 1) {
func = addList[0];
} else {
Functor* current = mulList[0];
for(int i = 0; i<opList.size(); i++) {
if(opList[i]) {
current = new Times(current, mulList[i+1]);
} else {
current = new Divides(current, mulList[i+1]);
}
}
func = current;
}};
powExp returns [Functor* func]
@init {
std::vector<Functor*> expList;
}
: e1=unarExp {expList.push_back($e1.func);} ('^' e2=unarExp {expList.push_back($e2.func);})?
{
if(expList.size() == 1) {
func = expList[0];
} else {
func = new Power(expList[0], expList[1]);
}};
unarExp returns [Functor* func]
: SQRT '(' e=addExp ')' {func = new Sqrt($e.func);}
| SIN '(' e=addExp ')' {func = new Sin($e.func);}
| COS '(' e=addExp ')' {func = new Cos($e.func);}
| TAN '(' e=addExp ')' {func = new Tan($e.func);}
| EXP '(' e=addExp ')' {func = new Exp($e.func);}
| LOG '(' e=addExp ')' {func = new Log($e.func);}
| ABS '(' e=addExp ')' {func = new Abs($e.func);}
| MAX '(' e1=addExp ',' e2=addExp ')' {func = new Max($e1.func,$e2.func);}
| MIN '(' e1=addExp ',' e2=addExp ')' {func = new Min($e1.func,$e2.func);}
| e=atom {func = $e.func;}
;
atom returns [Functor* func]
: INT {func = new Constant(atoi($INT.text));}
| FLOAT {func = new Constant(atof($FLOAT.text));}
| 'pi' {func = new Constant(PI);}
| 'e' {func = new Constant(E);}
| 'x' {func = new Variable();}
| '(' e=addExp ')' {func = $e.func;}
;
SQRT: 'Sqrt';
SIN : 'Sin';
COS : 'Cos';
TAN : 'Tan';
EXP : 'Exp';
LOG : 'Log';
ABS : 'Abs';
MAX : 'Max';
MIN : 'Min';
INT : '0'..'9'+;
FLOAT : ('0'..'9')+ '.' ('0'..'9')* EXPONENT?
| '.' ('0'..'9')+ EXPONENT?
| ('0'..'9')+ EXPONENT
;
WS : ( ' ' | '\t') {$channel=HIDDEN;};
fragment
EXPONENT : ('e'|'E') ('+'|'-')? ('0'..'9')+ ;
最佳答案
antlr3.h文件是ANTLR运行时的主头文件。您可以从http://www.antlr3.org/download/C/获取此运行时,但是此页面暂时不可用。
对于调用:ANTLR为您可以分别调用的每个解析器规则生成一个函数。通常,您需要设置解析器和词法分析器,然后调用解析器顶级规则,在这种情况下,可能是parse()。
我有一个调用的MySQL语言解析器:
_input = antlr3StringStreamNew((pANTLR3_UINT8)_text, _input_encoding, _text_length, (pANTLR3_UINT8)"mysql-script");
_input->setUcaseLA(_input, ANTLR3_TRUE); // Make input case-insensitive. String literals must all be upper case in the grammar!
_lexer = MySQLLexerNew(_input);
_tokens = antlr3CommonTokenStreamSourceNew(ANTLR3_SIZE_HINT, TOKENSOURCE(_lexer));
_parser = MySQLParserNew(_tokens);
_ast = _parser->query(_parser);
ANTLR3_UINT32 error_count = _parser->pParser->rec->getNumberOfSyntaxErrors(_parser->pParser->rec);
if (error_count > 0)
log_debug3("%i errors found\n", error_count);
区分大小写取决于您的解析器。尝试一下。
关于c++ - 在C++程序中使用ANTLR3,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22750035/