1

Cでトークンを識別するためのソフトウェアを実行する必要があります。次のコードがあります。

*main = do
   x <- readFile "progc.c"
   let resultado = lexCmm X
   print resultado
lexCmm :: String -> [Tok]
  lexCmm X = case X of
    c:cs   | isSpace c     -> lexCmm cs
    c:cs   | isAlpha c     -> getId s
    c:cs   | isDigit c     -> getInt s
    c:d:cs | isSymb [c,d]  -> TS [c,d] : lexCmm cs
    c:cs   | isSymb [c]    -> TS [c]   : lexCmm cs
    _                      -> []  
   where
    getId s  = lx i : lexCmm cs where (i,cs) = span isIdChar s
    getInt s = TI (read i) : lexCmm cs where (i,cs) = span isDigit s
    isIdChar c = isAlpha c || isDigit c
    lx i = if isReservedWord i then TS i else TI i

  isSymb s = elem s $ words "++ -- == <= >= ++ { } = , ; + * - ( ) < >"

  isReservedWord w = elem w $ words "else if int main printInt return while"*

エラーは次のとおりです。

file:{Hugs}\prog.hs:7 - Syntax error in input (unexpected `=')
4

2 に答える 2

5

変数名に大文字を使用するという前述のエラーに加えてX、インデントエラーがあります。の定義式lexCmmはインデントされていますが、左端の列から開始する必要があります。

その行のインデントを解除した場合

lexCmm :: String -> [Tok]
lexCmm x = case x of

およびの定義もisSymbisReservedWord他のエラーが発生します。

式の選択肢は、キーワードcaseよりもさらにインデントする必要があります。case

c:cs   | isAlpha c     -> getId s
c:cs   | isDigit c     -> getInt s

スコープ内にないエンティティを使用sします(したがって、の引数をlexCmms、またはこれら2つsをに変更する必要がありますx

getInt s = TI (read i) : lexCmm cs where (i,cs) = span isDigit s

のコンストラクターが引数TITok取ることを強くお勧めしますが、Int

lx i = if isReservedWord i then TS i else TI i

に適用しようとしますString。あなたはおそらくTI (read i)そこに欲しいでしょう。

タイプのクイックモックアップを含む次のコードはTokコンパイルされます。

module Toks where

import Data.Char

data Tok
    = TS String
    | TI Int
      deriving Show

main = do
   x <- readFile "progc.c"
   let resultado = lexCmm x
   print resultado

lexCmm :: String -> [Tok]
lexCmm s = case s of       -- No indentation for function definition
            c:cs   | isSpace c     -> lexCmm cs    -- alternatives indented further
            c:cs   | isAlpha c     -> getId s      -- than the `case', all to the same level
            c:cs   | isDigit c     -> getInt s
            c:d:cs | isSymb [c,d]  -> TS [c,d] : lexCmm cs
            c:cs   | isSymb [c]    -> TS [c]   : lexCmm cs
            _                      -> []  
      where  -- `where' indented less than the `case', so that it scopes over all alternatives
        getId s  = lx i : lexCmm cs where (i,cs) = span isIdChar s
        getInt s = TI (read i) : lexCmm cs where (i,cs) = span isDigit s
        isIdChar c = isAlpha c || isDigit c
        lx i = if isReservedWord i then TS i else TI (read i)

isSymb s = elem s $ words "++ -- == <= >= ++ { } = , ; + * - ( ) < >"

isReservedWord w = elem w $ words "else if int main printInt return while"
于 2012-12-24T00:01:54.673 に答える
1

Haskellの変数は小文字で始める必要があります。大文字で始まる識別子は型として解釈されます。

大文字Xはここで問題を引き起こしている可能性があります:

  lexCmm X = case X of

そしてここであなたは小文字と大文字を混ぜていますx

  x <- readFile "progc.c"
  let resultado = lexCmm X

これらすべてを小文字に置き換えるとx、問題が解決する場合があります。

于 2012-12-23T23:52:26.510 に答える