2014-03-30 3 views
0

현재 문자열 (단일 변수 'x'의 함수)을 입력으로 사용하여 해당 함수의 미분을 출력하는 응용 프로그램을 작성하고 있습니다. 프로그램의 후반부는 현재 문제가 아니며 문제가되는 것은 문자열에서 함수를 "읽는"것뿐입니다. ANTLRv3을 사용하여 C 목표를 달성하려고 노력하고 있지만 작동시키지 못합니다. 현재 "antlr3.h"헤더 파일이 없습니다. 필자는 어디서나 찾을 수 없습니다. 내 두 번째 문제는 생성 된 파서를 호출하는 것입니다. ANTLR 코드가 아래에 게시 됨)에 대한 C (++) 코드는 무엇이겠습니까? 어떻게 작동시킬 수 있습니까? 사전에C++ 프로그램에서 ANTLR3 사용

감사합니다,

넥타이

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')+ ; 

답변

1

antlr3.h 파일은 ANTLR 런타임의 기본 헤더 파일입니다. 이 런타임을 http://www.antlr3.org/download/C/에서 얻을 수 있지만이 페이지를 사용할 수없는 시점입니다.

호출의 경우 : ANTLR은 개별적으로 호출 할 수있는 각 구문 분석기 규칙에 대한 함수를 생성합니다. 일반적으로 파서와 렉서를 설정 한 다음 파서의 최상위 규칙을 호출합니다. 아마도 파스 (parse)()입니다.

_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); 

소문자 구분이 파서에 따라 달라집니다

나는 내가 그렇게 호출 MySQL의 언어에 대한 파서를 가지고있다. 그것으로 조금 실험 해보십시오.