我想我已经非常努力地研究了我的问题所以我在这里。
我有一个“文件意外结束”错误 6 colunm 33。
我已经尝试了很多解决方案来解决我的问题。
这是我的代码和我要解析的文件。
以下是我要解析的文字:
ifc.txt:
#9512= IFCBUILDINGSTOREY('3y21AUC9X4yAqzLGUny16E',#16,'Story',$,$,#9509,$,$,.ELEMENT.,6200.);
#9509= IFCLOCALPLACEMENT(#115,#9506);
#9506= IFCAXIS2PLACEMENT3D(#9502,#9498,#9494);
#9502= IFCCARTESIANPOINT((0.,0.,6200.));
#9498= IFCDIRECTION((0.,0.,1.));
#9494= IFCDIRECTION((1.,0.,0.));
以下是代码:
code.hs:
import Text.ParserCombinators.Parsec
main = do
f <- readFile "ifc.txt"
let m = (parse ifc "" f)
print m
ifc :: Parser IfcModel
ifc = many ifcentry
ifcentry = do
string "#"
i <- idt
string "= "
name <- idt
string "("
prop <- idt
string ")"
string ";"
string "\n"
return (i,name,prop)
idt = many (letter <|> digit <|> char ','
<|> char '$' <|> char ')' <|> char '\''
<|> char '=' <|> char ';' <|> char '\n'
<|> char ' ' <|> char '(' <|> char '#'
<|> char '.' <|> char '\r')
感谢你的帮助,我应该早点检查一下我的anwser,因为我自己工作,我发现asolution我会发布它,当我可以(8小时左边的新手像我一样,声誉低于10)
再次感谢。
答案 0 :(得分:4)
sepBy
而不是在ifcentry
你的ifcentry
期望最后一行换行,而你的输入没有换行,这就是EOF出乎意料的原因。
从string "\n"
删除ifcentry
,然后定义
ifc :: Parser IfcModel
ifc = ifcentry `sepBy` (char '\n')
此外,您的idt
解析器不必要很长。
idt = many (letter <|> digit <|> oneOf ".,;' =#$()\n\r")
ifcentry
虽然我在,但我会写
ifcentry = do
char '#'
i <- idt
string "= "
name <- idt
prop <- parens idt
char ';'
return (i,name,prop)
因为parens
(解析一个空心括号,你的idt
内容,然后是一个小括号)整理它并使其更清晰。
main
我也写
main = fmap (parse ifc "") (readFile "ifc.txt") >>= print
当然不需要
let m = (parse ifc "" f)
print m
因为你也可以这样做
print (parse ifc "" f)
答案 1 :(得分:1)
另外还有@enough rep回复评论的答案
我会更进一步,并在
的行中声明一些内容data IFCType = IFCBuildingStorey ....
| IFCLocalPlacement ....
| IFCAxis2Placement3D ....
| IFCCartesianpoint Double Double Double
| IFCDirection ....
deriving Show
和
type ID = Integer
type IFCElement = (ID,IFCType)
我将以CartesianPoint为例展示
ifctype :: Parser IFCType
ifctype = do string "IFC"
buildingStorey
<|> localPlacement
<|> axis2Placement3D
<|> cartesianpoint
<|> direction
buildingStorey :: Parser IFCType
buildingStorey = do string "BUILDINGSTOREY"
return IFCBuildingStorey
localPlacement :: Parser IFCType
localPlacement = do string "LOCALPLACEMENT"
return IFCLocalPlacement
axis2Placement3D :: Parser IFCType
axis2Placement3D = do string "AXIS2PLACEMENT3D"
return IFCAxis2Placement3D
cartesianpoint :: Parser IFCType
cartesianpoint = do string "CARTESIANPOINT"
char '('
char '('
x <- double
char ','
y <- double
char ','
z <- double
char ')'
char ')'
return $ IFCCartesianpoint x y z
double :: Parser Double
double = do d <- many1 (digit <|> char '.')
return $ read d
direction :: Parser IFCType
direction = do string "DIRECTION"
return IFCDirection
这具有您输入模型的额外优势。
答案 2 :(得分:0)
感谢大家的帮助,我应该早点检查一下,因为我自己工作并最终找到了解决方案:
import Text.ParserCombinators.Parsec
main = do
f <- readFile "ifc.txt"
let m = (parse ifc "" f)
print m
type IfcIdt = String
type IfcName = String
type IfcProp = [String]
type IfcModel = [(IfcIdt,IfcName,IfcProp)]
ifc :: Parser IfcModel
ifc = many ifcentry
ifcentry = do
string "#"
i <- idtnumber
string "= "
name <- idtname
opening
prop <- ifcprop
closing
eol
return (i,name,prop)
idtnumber = many digit
idtname = many (letter <|> digit)
ifcprop = sepBy prop (char ',')
prop = many (noneOf "=,();\n")
eol = string ";\n"
opening = try (string "((")
<|> string "("
closing = try (string "))")
<|> string ")"