我目前正在开发一个将字符串(单个变量“ 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/

10-11 00:56