2010-01-21 3 views
2

Antlr 문법에 왼쪽 재귀 문제가 있습니다. 내가 왜 문제가 있는지 이해할 수는 있지만 해결책을 생각할 수는 없다. 내 데이터 유형 규칙의 마지막 줄에 문제가 있습니다. 의Antlr 재귀 문제가 왼쪽

어떤 도움을 것입니다 : - 일을하지만 불행히도 그것은 보이지 않는다

grammar Test; 

options {output=AST;ASTLabelType=CommonTree;} 
tokens {FUNCTION; ATTRIBUTES; CHILDREN; COMPOSITE;} 

program  : function ; 
function : ID (OPEN_BRACKET (attribute (COMMA? attribute)*)? CLOSE_BRACKET)? (OPEN_BRACE function* CLOSE_BRACE)? SEMICOLON? -> ^(FUNCTION ID ^(ATTRIBUTES attribute*) ^(CHILDREN function*)) ; 

attribute : ID (COLON | EQUALS) datatype -> ^(ID datatype); 

datatype : ID  -> ^(STRING["id"] ID) 
      | NUMBER -> ^(STRING["number"] NUMBER) 
      | STRING -> ^(STRING["string"] STRING) 
      | BOOLEAN -> ^(STRING["boolean"] BOOLEAN) 
      | array -> ^(STRING["array"] array) 
      | lookup -> ^(STRING["lookup"] lookup) 
      | datatype PLUS datatype -> ^(COMPOSITE datatype datatype) ; 

array  : OPEN_BOX (datatype (COMMA datatype)*)? CLOSE_BOX -> datatype* ; 
lookup  : OPEN_BRACE (ID (PERIOD ID)*) CLOSE_BRACE -> ID* ; 

NUMBER 
    : ('+' | '-')? (INTEGER | FLOAT) 
    ; 

STRING 
    : '"' (ESC_SEQ | ~('\\'|'"'))* '"' 
    ; 

BOOLEAN 
    : 'true' | 'TRUE' | 'false' | 'FALSE' 
    ; 

ID : (LETTER|'_') (LETTER | INTEGER |'_')* 
    ; 

COMMENT 
    : '//' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;} 
    | '/*' (options {greedy=false;} : .)* '*/' {$channel=HIDDEN;} 
    ; 

WHITESPACE : (' ' | '\t' | '\r' | '\n') {$channel=HIDDEN;} ; 

COLON : ':' ; 
SEMICOLON : ';' ; 

COMMA : ',' ; 
PERIOD : '.' ; 
PLUS : '+' ; 
EQUALS : '=' ; 

OPEN_BRACKET : '(' ; 
CLOSE_BRACKET : ')' ; 

OPEN_BRACE : '{' ; 
CLOSE_BRACE : '}' ; 

OPEN_BOX : '[' ; 
CLOSE_BOX : ']' ; 

fragment 
LETTER 
    : 'a'..'z' | 'A'..'Z' 
    ; 

fragment 
INTEGER 
    : '0'..'9'+ 
    ; 

fragment 
FLOAT 
    : INTEGER+ '.' INTEGER* 
    ; 

fragment 
ESC_SEQ 
    : '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\') 
    ; 

을 내가 ANTLR이 문제를 해결하는 기능을 제공하는 작동하여 개발입니다 : 당신이 볼 수 있도록 나는 전체 문법을 포함했다 잘해라.

감사합니다.

편집 : 여기

내가 구현하기 위해 노력하고있어 언어의 예입니다/예를 들어, 그래서

<FunctionName> <OptionalAttributes> <OptionalChildFunctions> 

을 구문 분석 :

ForEach(in:[1,2,3,4,5] as:"i") { 
    Switch(value:{i}) { 
    Case(value:3) { 
     Print(message:"This is the number 3") 
    } 

    Default { 
     Print(message:"This isn't the number 3") 
    } 
} 
} 

답변

2

좋아, 이것은 트릭을 할해야 :

grammar Test; 

/************************************** PARSER **************************************/ 
program 
    : function EOF 
    ; 

function 
    : ID (OPEN_PAREN (attribute (COMMA attribute)*)? CLOSE_PAREN)? 
     (OPEN_BRACE function* CLOSE_BRACE)? 
     SEMICOLON? 
    ; 

attribute 
    : ID (COLON | EQUALS)? expression 
    ; 

expression 
    : atom (PLUS atom)* 
    ; 

atom 
    : ID 
    | STRING 
    | BOOLEAN 
    | NUMBER 
    | array 
    | lookup 
    ; 

array 
    : OPEN_BOX (expression (COMMA expression)*)? CLOSE_BOX 
    ; 

lookup 
    : OPEN_BRACE (ID (PERIOD ID)*) CLOSE_BRACE 
    ; 

/************************************** LEXER **************************************/ 
NUMBER   : ('+' | '-')? (INTEGER | FLOAT) 
       ; 

STRING   : '"' (ESC_SEQ | ~('\\'|'"'))* '"' 
       ; 

BOOLEAN   : 'true' | 'TRUE' | 'false' | 'FALSE' 
       ; 

ID    : (LETTER|'_') (LETTER | INTEGER |'_')* 
       ; 

COMMENT   : '//' ~('\n'|'\r')* ('\r'? '\n'| EOF) {$channel=HIDDEN;} 
       | '/*' (options {greedy=false;} : .)* '*/' {$channel=HIDDEN;} 
       ; 

WHITESPACE  : (' ' | '\t' | '\r' | '\n') {$channel=HIDDEN;} ; 

COLON   : ':' ; 
SEMICOLON  : ';' ; 

COMMA   : ',' ; 
PERIOD   : '.' ; 
PLUS   : '+' ; 
EQUALS   : '=' ; 

OPEN_PAREN  : '(' ; 
CLOSE_PAREN  : ')' ; 

OPEN_BRACE  : '{' ; 
CLOSE_BRACE  : '}' ; 

OPEN_BOX  : '[' ; 
CLOSE_BOX  : ']' ; 

fragment 
LETTER   : 'a'..'z' | 'A'..'Z' ; 
fragment 
INTEGER   : '0'..'9'+ ; 
fragment 
FLOAT   : INTEGER+ '.' INTEGER* ; 
fragment 
ESC_SEQ   : '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\') ; 

OPEN_BRACKETCLOSE_BRACKET의 이름을 OPEN_PARENCLOSE_PAREN으로 변경했습니다. 둥근 것들은 ()은 괄호로, 사각형은 []이며 괄호 (상자라고 부르지 만 상자라고 부르는 것은 IMO를 해가되지 않습니다)라고합니다.

+0

감사합니다. Bart. 예, 당신은 그것을 못 박는 것처럼 보였습니다! 나는 여기에서 잘해야한다! 고마워요! 많이 감사드립니다 :) –

+0

리치에 대해 듣기 좋네요, 당신은 환영합니다. –