F # 형식 구문을 구문 분석하려고합니다. 나는 [F] 파섹 문법을 쓰기 시작 문제로 실행, 그래서 나는이 아래로 the grammar을 단순화 : 나는 full chapter of a book dedicated to explaining it이 있기 때문에Parsec : backtracking not working
type ::= identifier | type -> type
identifier ::= [A-Za-z0-9.`]+
FParsec 문제로 실행 한 후, 나는 파섹로 전환. 이 문법에 대한 나의 코드는
typeP = choice [identP, arrowP]
identP = do
id <- many1 (digit <|> letter <|> char '.' <|> char '`')
-- more complicated code here later
return id
arrowP = do
domain <- typeP
string "->"
range <- typeP
return $ "("++domain++" -> "++range++")"
run = parse (do t <- typeP
eof
return t) "F# type syntax"
문제는 파섹 내가 시도 우선은 순서를했다
> run "int"
Right "int"
-- works!
> run "int->int"
Left "F# type syntax"
unexpected "-"
expecting digit, letter, ".", "`" or end of input
-- doesn't work!
때문에, 기본적으로 철수하지 않는다는 것입니다이다 typeP :
typeP = choice [arrowP, identP]
그러나 문법이 왼쪽 재귀 적이므로 오버플로가 발생합니다. typeP가 identP
을 시도하지 않습니다. arrowP
을 계속해서 시도하기 때문입니다.
typeP = choice [try identP, arrowP]
을하지만 내가 아무것도 (1) 스택 오버 플로우 또는 (2) 비 인식의 기본 동작을 변경 것 같다 - 식별자 다음 ">"다음 : 나는 예를 들어, 다양한 장소에서 try
을 시도했다.
필자의 실수는 Parsec 문법을 성공적으로 작성한 사람이라면 누구나 쉽게 알 수 있습니다. 누군가 그것을 지적 할 수 있습니까?
좋은 설명. 여러분이 주목 한 것처럼, 문제의 근본 원인은 arrowP가 typeP로 내려갈 수있는 사이클을 중단해야한다는 것입니다. typeP는 typeP로 내려갈 수 있습니다. 나는 당신의'parens' 사례가 특히 밝다고 생각합니다. – kvb
그래서 Parsec 문법은 LR (1) 문법과 기본적으로 같은 비 구성 문제를 가지고 있습니다. 따라서 모든 규칙의 왼쪽 가장자리가 모호하지 않은 문자로 다시 작성되도록 전체 문법을 계획해야합니다. 오 잘, 파섹이 마술이라고 생각하는 것보다 더 잘 알아야한다고 생각합니다. –