Megaparse c: вложенные блоки с отступами едят слишком много - PullRequest
1 голос
/ 16 февраля 2020

У меня проблемы с вложенными блоками с отступами, глотающими новые строки. Я хочу разобрать определение функции (или, точнее, пропустить все тело, fun c. Def. Не обязательно верхнего уровня).

Пример:

func F() -> void: pass

func m():
  pass

func f(a:= 4, b, c:X) -> Y:
    if a >= 0:
        if b > 4:
            return b
        else:
            return c.y(-b)
    else: return c.y(b)

Мой код:

pFunc :: Parser Node
pFunc = (try pMultiline <|> pOneline) & dbg "pFunc"
  where
    pOneline = do
      (name, args, ret) <- pFuncHead
      pStatement
      return $ NFuncDef name args ret
    pMultiline = (L.indentBlock scn pMultilineIB) & dbg "pMultiline"
    pMultilineIB = do
      (name, args, ret) <- pFuncHead & dbg "pMultilineIB pFuncHead"
      return $ L.IndentSome Nothing (\_ -> return $ NFuncDef name args ret) body
    body = (try nested <|> void pSomeTillEol) & dbg "body"
    nested = (L.indentBlock scn nestedIB) & dbg "nested"
    nestedIB = do
      pStatement
      return $ L.IndentSome Nothing (const skip) body

pFuncHead, pStatement и pSomeTillEol не используют конечные новые строки (только scn делает, я использовал этот учебник в качестве шаблона).

Побежал с "func m():\n pass\n\n":

pMultilineIB pFuncHead> IN: "func m():<newline>  pass<newline><newli <…>
pMultilineIB pFuncHead> MATCH (COK): "func m():"
pMultilineIB pFuncHead> VALUE: ("m",[],Nothing)

nested> IN: "pass<newline><newline>"
nested> MATCH (CERR): "pass<newline><newline>"
nested> ERROR:
nested> offset=18:
nested> incorrect indentation (got 1, should be greater than 3)

pSomeTillEol> IN: "pass<newline><newline>"
pSomeTillEol> MATCH (COK): "pass"
pSomeTillEol> VALUE: "pass"

body> IN: "pass<newline><newline>"
body> MATCH (COK): "pass"
body> VALUE: ()

pMultiline> IN: "func m():<newline>  pass<newline><newli <…>
pMultiline> MATCH (COK): "func m():<newline>  pass<newline><newli <…>
pMultiline> VALUE: NFuncDef "m" [] Nothing

pFunc> IN: "func m():<newline>  pass<newline><newli <…>
pFunc> MATCH (COK): "func m():<newline>  pass<newline><newli <…>
pFunc> VALUE: NFuncDef "m" [] Nothing

Почему pMultiline, так что я предполагаю, что indentBlock съедает новые строки? Как это исправить?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...