За да постигна нечувствителни към регистъра инфикс оператори, използвайки OperatorPrecedenceParser
, обработвам предварително входа, анализирайки го като текст, разделен от низови литерали. След това текстовата част се търси за инфикс оператори, които трябва да бъдат с главни букви (за да съответстват на оператора, както е известен на OPP
). След това се извършва действителният анализ.
Въпросът ми е, могат ли и двете фази да бъдат комбинирани в един анализатор? опитах
// preprocess: Parser<string,_>
// scalarExpr: Parser<ScalarExpr,_>
let filter = (preprocess .>> eof) >>. (scalarExpr .>> eof)
но се проваля в края на входа, привидно очаквайки scalarExpr
. Входът може да бъде анализиран от preprocess
и scalarExpr
независимо, така че предполагам, че това е проблем с eof
, но изглежда не мога да го разбера правилно. Възможно ли е това?
Ето другите анализатори за справка.
let stringLiteral =
let subString = manySatisfy ((<>) '"')
let escapedQuote = stringReturn "\"\"" "\""
(between (pstring "\"") (pstring "\"") (stringsSepBy subString escapedQuote))
let canonicalizeKeywords =
let keywords =
[
"OR"
"AND"
"CONTAINS"
"STARTSWITH"
"ENDSWITH"
]
let caseInsensitiveKeywords = HashSet(keywords, StringComparer.InvariantCultureIgnoreCase)
fun text ->
let re = Regex(@"([\w][\w']*\w)")
re.Replace(text, MatchEvaluator(fun m ->
if caseInsensitiveKeywords.Contains(m.Value) then m.Value.ToUpperInvariant()
else m.Value))
let preprocess =
stringsSepBy
((manySatisfy ((<>) '"')) |>> canonicalizeKeywords)
(stringLiteral |>> (fun s -> "\"" + s + "\""))
preprocess
връща нов низ с операторите с главни букви. - person Daniel   schedule 15.05.2013>>=
вместо>>.
, но типовете не работят, така че в момента съм объркан. - person Daniel   schedule 15.05.2013parse
два пъти, веднъж за всеки анализатор? Няма начин да ги комбинирате? - person Daniel   schedule 15.05.2013preprocess
е анализатор, който връща предварително обработения низ. Ако това е правилно, трябва да създадете нов CharStream за този низ и да стартирате втория анализатор на този CharStream, напр. с помощта на runParserOnString. Въпреки това, целият подход е доста грозен. Бихте ли могли да се измъкнете само с поддържането на разумните комбинации от главни и малки букви, т.е. - person Stephan Tolksdorf   schedule 15.05.2013