나는 만들고있는 언어에 대한 파싱 단계를 진행하고 있으며 다음과 관련하여 어려움을 겪고 있습니다. 연산자 우선 순위 구문 분석기에 들여 쓰기 검사를 삽입하는 방법은 무엇입니까?
let test2 = // I'd like this to be an error.
"""
2
+ 2
"""
let result = run (spaces >>. expr) test2
val result : ParserResult<CudaExpr,unit> =
Success: Add (LitInt32 2,LitInt32 2)
은 이미 용어가 잘못
2 +
2
들여 쓰기 나에게 오류를 줄 때 다음과 같은 예를 만들기 위해 관리하지만, 운전자가 잘못 들여 쓰기 수준에하지 않는 경우. 구문 분석 전 검사와 같은 것이 필요합니다.
let operators expr i =
let f expr (s: CharStream<_>) = if i <= s.Column then expr s else pzero s
opp.TermParser <- f expr
f opp.ExpressionParser
위의 기능은 운영자 단계가 어떻게 구성되어 있는지 그리고 당신이 볼 수 있듯이, 용어 파서는 들여 쓰기 검사를 수행하는 기능에 싸여 얻을하지만 마지막 줄에 결함이 있습니다.
다음은 전체 구문 분석기의 간단한 예입니다.
#r "../../packages/FParsec.1.0.2/lib/net40-client/FParsecCS.dll"
#r "../../packages/FParsec.1.0.2/lib/net40-client/FParsec.dll"
open FParsec
type Expr =
| V of string
| Add of Expr * Expr
let identifier = many1Satisfy2L isAsciiLetter (fun x -> isAsciiLetter x || isDigit x || x = ''') "identifier" .>> spaces |>> V
let indentations expressions (s: CharStream<_>) =
let i = s.Column
let expr_indent expr (s: CharStream<_>) =
let expr (s: CharStream<_>) = if i <= s.Column then expr s else pzero s
many1 expr s
expr_indent (expressions i) s
let expr =
let opp = new OperatorPrecedenceParser<_,_,_>()
opp.AddOperator(InfixOperator("+", spaces, 6, Associativity.Left, fun x y -> Add(x,y)))
let operators expr i =
let f (s: CharStream<_>) = if i <= s.Column then expr s else pzero s
opp.TermParser <- f
f opp.ExpressionParser
let rec expr s = indentations (operators identifier) s
expr
let test2 = // I'd like this to be an error.
"""
a
+
b
"""
let result = run (spaces >>. expr) test2
전체 구문 분석기는 here입니다.
[사용자 상태] (http://www.quanttec.com/fparsec/users-guide/parsing-with-user-state.html)를 활용하여 들여 쓰기 레벨을 추적하고 싶을 것이라고 상상해보십시오. 표현의 조건을 확인한 다음 연산자 나 다른 용어를 파싱 할 때 일관성이 있는지 확인하십시오. – rmunn
나는 그것을 고려했다. 그러나 나는이 방법이 더 단순하다는 것을 알았다. –