Я написал лексер в Alex, и я пытаюсь подключить его к парсеру, написанному на Happy. Я постараюсь изо всех сил суммировать свою проблему, не вставляя огромные куски кода.Что вызывает счастье, чтобы вывести ошибку синтаксического анализа?
Я знаю из моих модульных тестов моего лексере, что строка "\x7"
является lexed к:
[TokenNonPrint '\x7', TokenEOF]
Моего типа лексемы (выплюнуть лексер), является Token
. Я определил lexWrap
и alexEOF
, как описано here, который дает мне следующий заголовок и символические объявления:
%name parseTokens
%tokentype { Token }
%lexer { lexWrap } { alexEOF }
%monad { Alex }
%error { parseError }
%token
NONPRINT {TokenNonPrint $$}
PLAIN { TokenPlain $$ }
Я призываю парсер + лексический анализатор комб следующее:
parseExpr :: String -> Either String [Expr]
parseExpr s = runAlex s parseTokens
А вот мои первые несколько производств:
exprs :: { [Expr] }
exprs
: {- empty -} { trace "exprs 30" [] }
| exprs expr { trace "exprs 31" $ $2 : $1 }
nonprint :: { Cmd }
: NONPRINT { NonPrint $ parseNonPrint $1}
expr :: { Expr }
expr
: nonprint {trace "expr 44" $ Cmd $ $1}
| PLAIN { trace "expr 37" $ Plain $1 }
Я уеду из деклараций типа данных Expr
и NonPrint
, так как они длинны, и только конструкторы Cmd
и NonPrint
здесь. Функция parseNonPrint
определяется в нижней части parse.y как:
parseNonPrint :: Char -> NonPrint
parseNonPrint '\x7' = Bell
Кроме того, моя ошибка функции обработки выглядит следующим образом:
parseError :: Token -> Alex a
parseError tokens = error ("Error processing token: " ++ show tokens)
Написано так, я надеюсь, следующий hspec тест пройти:
parseExpr "\x7" `shouldBe` Right [Cmd (NonPrint Bell)]
Но вместо этого, я вижу "exprs 30"
печать раз (хотя я бегу 5 различных уни t) и все мои тесты parseExpr
return Right []
. Я не понимаю, почему это было бы дело, но я изменил exprs
производство, чтобы предотвратить его:
exprs :: { [Expr] }
exprs
: expr { trace "exprs 30" [$1] }
| exprs expr { trace "exprs 31" $ $2 : $1 }
Теперь все мои тесты не на первом маркере они попали --- parseExpr "\x7"
терпит неудачу с:
uncaught exception: ErrorCall (Error processing token: TokenNonPrint '\a')
И я полностью смущен, так как я ожидаю, что синтаксический анализатор примет путь exprs -> expr -> nonprint -> NONPRINT
и добьется успеха. Я не понимаю, почему этот ввод поставил бы синтаксический анализатор в состояние ошибки. Ни один из операторов trace
не попал (оптимизирован?).
Что я делаю неправильно?
Можете ли вы указать нам на код - т. Е. Репозиторий github? – ErikR
@ user5402 https://github.com/pscollins/ansi-parser имеет весь код. На данный момент это немного небрежно, особенно маркировка тестов. –