2014-09-19 6 views
0

Ruby 용 Citrus와 같은 문법을 사용하여 결국 부울 논리가 될 내용을 처리하려고합니다. 재귀 문제가 발생하지만 정확한 이유는 확실하지 않습니다. 여기Citrus for Parsing Expression 문법을 사용하여 스택 레벨이 너무 깊음

COMMANDWORD # MYCOMMENT 

(고급 물건을 처리하도록 구성)의 내 감귤류 문법 : : 여기 프로세스에 노력하고있어 텍스트의 (그것은 매우 끝에 줄 바꿈을해야한다)

grammar Grammar 
    rule commandset 
    command+ 
    end 

    rule command 
    identifier command_detail* comment_to_eol* "\n" 
    end 

    rule command_detail 
    assign_expr | expr 
    end 

    rule assign_expr 
    identifier ":=" expr 
    end 

    rule expr 
    # Stack overflow 
    or_expr | gtor_expr 
    # No problem! 
    # or_expr 
    end 

    rule or_expr 
    # Temporarily match everything except a comment... 
    [^#]+ 
    # What I think will be correct in the future... 
    # gtor_expr "OR" expr 
    end 

    rule gtor_expr 
    and_expr | gtand_expr 
    end 

    rule and_expr 
    gtand_expr "AND" gtor_expr 
    end 

    rule gtand_expr 
    not_expr | gtnot_expr 
    end 

    rule not_expr 
    "NOT" gtnot_expr | gtand_expr 
    end 

    rule gtnot_expr 
    parens_expr | identifier 
    end 

    rule parens_expr 
    "(" expr ")" 
    end 

    rule identifier 
    ws* [a-zA-Z0-9]+ ws* 
    end 

    rule ws 
    [ ] 
    end 

    rule comment_to_eol 
    "#" [^\n]* 
    end 
end 

중요한 것들은 규칙 expr과 규칙 or_expr에 있습니다. 나는 or_expr을 변경하여 주석을 제외한 모든 것을 일치시킵니다. 현재 expr 규칙을 고수하면 스택 오버플로가 발생합니다. 하지만 or_expr과 gtor_expr 사이에 선택 사항이 없도록 전환하면 정상적으로 작동합니다.

"선택"에 대한 나의 이해는 순서대로 평가하려고한다는 것입니다. 첫 번째 선택 에 실패하면 두 번째 시도가 시도됩니다. 이 경우 첫 번째 선택이 분명히 성공할 수 있으므로 두 번째 선택을하지 않으면 스택 오버플로가 발생하는 이유는 무엇입니까?

+1

:

난 당신이

not_expr -> "NOT" not_expr | gtnot_expr 

와 not_expr의 규칙을 바꿀 수 있습니다 그리고 당신은 정규 표현식 연산자를 사용하여 간단한 규칙을 시도해야한다고 생각 '는'gtor_expr'에 의존합니다. 무한 루프. –

+0

@ 마크 토마스 나는 그것이 이상하게 보인다는 것을 안다. 여기에서 산술 문법을 벗어나고 있습니다. https://github.com/mjackson/citrus/blob/master/lib/citrus/grammars/calc.citrus. 이 경우'term '은'term '에 다시 의존하는'additive'에 의존한다는 것을 알아 두십시오. 두 경우 모두 앞에 특정 기호 (예 : "OR"또는 "AND")가 있어야한다고 지정하기 때문에 문제가되지 않는다고 생각합니다. – aardvarkk

+0

나는 @MarkThomas를 upvoted했다. 그러나 and_expr가 "AND"를 소비하기 때문에 나는 이것을 생성하지 않는다고 생각하지 않는다. – 1010

답변

1

gtand_expr -> not_expr 및 not_expr -> gtand_expr 때문에 루프가 발생할 수 있습니다. `gtor_expr`이 and_expr`에 따라 나타납니다, 언뜻

expr -> orexpr 
orexpr -> andexpr ("OR" andexpr)* 
andexpr -> notexpr ("AND" notexpr)* 
notexpr -> "NOT"? atomicexpr 
atomicexpr -> id | "(" expr ")" 
+0

두 개 이상 연속하지 않는 표현식을 허용하려면 "NOT"*을 사용하십시오. – 1010