基本上,我只是创建了一个解析器来打印一个逆波兰表示法表达式的派生树,它识别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表达式,但是它什么也不做或打印!如果有人能帮助我,我将非常感激
1条答案
按热度按时间cqoc49vn1#
基于这个问题,我认为您将
getContents
视为读取一行然后结束的“提示符”。但是getContents
读取 * 所有 * 行,直到流关闭。在大多数shell中,您可以使用Ctrl+D关闭流,因此getContents
完成。如果你只想解析一行代码,可以使用**
getLine :: IO String
**:字符串