用Alex和Happy创建的Haskell解析器由于main函数而不工作,有人能告诉我为什么吗?

gdx19jrr  于 6个月前  发布在  其他
关注(0)|答案(1)|浏览(60)

基本上,我只是创建了一个解析器来打印一个逆波兰表示法表达式的派生树,它识别RPN中内置的正则表达式,标记它们只识别RPN内置的表达式,并应该返回派生树。问题是main函数不做它的工作,但如果我手动运行main函数内部的内容,那么它只是做它应该做的事情!

--Alex lexer

识别RPN表达式中的所有标记:int数字和字符,用于基本操作+,-,*,/

{
    module Lexical (Token(..), lexer) where
}

%wrapper "basic"

$digit = [0-9]
@int = $digit+

tokens :-
    $white+     ;
    "--".*      ;
    \+          {\s -> TokenPlus}
    \-          {\s -> TokenMinus}
    \*          {\s -> TokenTimes}
    \/          {\s -> TokenDiv}
    @int        {\s -> TokenInt (read s)}

{
data Token
    = TokenPlus
    | TokenMinus
    | TokenTimes
    | TokenDiv
    | TokenInt Int
    deriving (Eq,Show)

            
lexer = alexScanTokens
}

字符串

--Happy parser

识别RPN中构建的所有表达式,并应使用数据构造器Exp打印等效的派生树。对于上下文,我知道我甚至可以使用Tree数据构造器,但Exp帮助我更好地理解我希望如何打印表达式。

{
module Main where
import Lexical
}

%name calc
%tokentype {Token}
%error {parseError}

%token
    '+'         {TokenPlus}
    '-'         {TokenMinus}
    '*'         {TokenTimes}
    '/'         {TokenDiv}
    int         {TokenInt $$}

%left '+' '-'
%left '*' '/'

%%

Exp : Exp Exp '+'       { Plus $1 $2 }
    | Exp Exp '-'       { Minus $1 $2 }
    | Exp Exp '*'       { Times $1 $2 }
    | Exp Exp '/'       { Div $1 $2 }
    | int               { Int $1 }

{
parseError :: [Token] -> a
parseError _ = error "ParseError"

data Exp = Plus Exp Exp
         | Minus Exp Exp
         | Times Exp Exp
         | Div Exp Exp
         | Int Int 
         deriving (Eq, Show)

main = do
        s <- getContents
        print(calc (lexer s))
}


问题出在main函数上:如果我只是运行例如

print (calc (lexer "3 4 5 + *"))


它只是返回我所期望的,也就是:

Times (Int 3) (Plus (Int 4) (Int 5))


但是如果我执行“happy parser.y”,然后执行“ghci parser.hs”,它会编译得很好,但是一旦我调用main函数,它就可以让我写我想要的RPN表达式,但是它什么也不做或打印!如果有人能帮助我,我将非常感激

cqoc49vn

cqoc49vn1#

基于这个问题,我认为您将getContents视为读取一行然后结束的“提示符”。但是getContents读取 * 所有 * 行,直到流关闭。在大多数shell中,您可以使用Ctrl+D关闭流,因此getContents完成。
如果你只想解析一行代码,可以使用**getLine :: IO String**:

main = do
  s <- getLine
  print (calc (lexer s))

字符串

相关问题