我想使用以下代码示例:
prop levelBasedAlerter uni { a b } \I ->
levelBasedAlerter a
| a > I ->
b: "ALERT: %a"
这应该是
Prop
Var "levelBasedAlerter"
Uni
PortSpecS " { a b }"
Lam
Var "I"
PatternMatchEnd
Indent 2
Var "levelBasedAlerter"
Var "a"
Indent 4
PatternGuard
Var "a"
Var ">"
Var "I"
PatternMatchEnd
Indent 6
Var "b"
DefinedByCol
StringLit "Alert: %a"
但是,我的 alex lexer 在第一行遇到错误时停止\
(在 后面有和没有空格\
)。
为什么会这样?词法分析器:
{
{-# LANGUAGE DeriveDataTypeable #-}
module Lexer where
import Data.Typeable
import Data.Data
import Data.List
import Data.List.Split
import Data.Char
import Debug.Trace
import Prelude hiding (lex)
import Control.Monad (liftM)
}
%wrapper "posn"
$digit = 0-9
@string = (. # [\" \\] )
$alpha = [a-zA-Z]
@real = ($digit+ \. | $digit * \. $digit +)
@boolLit = ("True"|"False")
@alphaNum = ($alpha|$digit)+
$bracketsOpen = [\(\[\{]
$bracketsClose = [\)\]\}]
$brackets = [ $bracketsOpen $bracketsClose]
@identifier = [^ : ! = \\ \ " $brackets]+
@commaOrSpace = (\,\ * | \ +)
@scopedIdentifier = @identifier(\.@identifier)+
@globalKeyword = (prop|mesh|let|omni|uni|let|using|module|import|where)
@port = (@identifier:\ *)?@identifier
@portSpec = ((@identifier|@scopedIdentifier):)?
" "*
\{\ * @port
(@commaOrSpace @port)*
" "*\}
@deepPortSpec = ((@identifier|@scopedIdentifier):)?
" "*
\{\ * @identifier: (. # \})+ \}
@indent = \n[\t\ ]+
tokens :-
@indent { \_ s -> Indent $ length s }
$white+ ;
"--".* ;
@globalKeyword { \_ keyword -> getTokenOf keyword }
$digit+ { \_ s -> IntL (read s) }
@real+ { \_ s -> DoubleL (read s) }
@boolLit { \_ s -> BoolL (read s) }
\" @string \" { \_ s -> StringLit (tail . init $ s) }
@portSpec { \_ s -> PortSpecS s }
@deepPortSpec { \_ s -> DeepPortSpecS s }
":" { \_ s -> DefinedByCol }
"," { \_ s -> Comma }
"!" { \_ s -> Negate }
"==" { \_ s -> Eq }
"=" { \_ s -> LetAssOp }
"~>" { \_ s -> Wire }
"->" { \_ s -> PatternMatchEnd }
$bracketsOpen { \_ s -> BracO s}
$bracketsClose { \_ s -> BracC s}
"||" { \_ s -> Or }
"|" { \_ s -> PatternGuard}
"!!" { \_ s -> AccessPort }
"\\" { \_ s -> Lam }
@scopedIdentifier {\_ s -> ScopedVar s }
@identifier { \_ s -> Var s }
{
clean :: String -> String
clean s = reverse $ rmWs $ reverse $ rmWs s
where rmWs = dropWhile (\c -> c ==' ' || c == '\t')
traceThis :: (Show a) => a -> a
traceThis a = trace ("DEBUG: " ++ show a) a
data Token
= Prop
| Mesh
| Module
| Import
| Where
| Var String
| BracO String
| BracC String
| Comma
| Eq
| PatternGuard
| Or
| ScopedVar String
| Omni
| Uni
| PortSpecS String
| DeepPortSpecS String
| DefinedByCol -- ':' after definitions
| Indent Int
| PatternMatchEnd -- '->' after PM
| Negate
| Let
| LetAssOp -- '=' in let x = ...
| Wire
| AccessPort
| Using
| Lam
| StringLit String
| IntL Int
| DoubleL Double
| BoolL Bool
| EOF
deriving (Eq,Show,Data)
getTokenOf :: String -> Token
getTokenOf s = fromConstr
$ head $ filter ((==s) . map toLower . showConstr)
$ dataTypeConstrs $ dataTypeOf $ Prop
}
我认为这与我如何匹配\
令牌有关。但是,我尝试过匹配它
'\'
'\\'
"\"
"\\"
\\
\
还有一个正则表达式,但似乎没有任何效果。
\
亚历克斯有什么奇怪的行为吗?还是我看不到的其他一些微不足道的错误?
更新
我现在尝试将其更改@identifier
为:
@identifier = (. # [ : ! = \\ \ " $brackets])+
以 alexy 方式进行“除了 x 之外的任何事情”匹配,但这并没有改变输出中的任何内容。