diff --git a/IdlPpr.hs b/IdlPpr.hs
new file mode 100644
--- /dev/null
+++ b/IdlPpr.hs
@@ -0,0 +1,33 @@
+------------------------------------------------------------------
+-- |
+-- Program     :  idlppr          
+-- Copyright   :  (c) Dmitry Golubovsky, 2009
+-- License     :  BSD-style
+-- 
+-- Maintainer  :  golubovsky@gmail.com
+-- Stability   :  experimental
+-- Portability :  portable
+-- 
+--
+--
+-- Parse and pretty-print IDL declarations: good for testing.
+------------------------------------------------------------------
+
+module Main where
+
+import Language.WebIDL.Lexer
+import Language.WebIDL.Parser
+import Language.WebIDL.PrettyPrint
+
+import Prelude hiding (putStrLn)
+import Control.Monad
+import System.Exit
+import System.IO.UTF8
+
+main = do
+  tks <- lexStdin
+  let pp = parseIDL tks
+  case pp of
+    Right p -> putStrLn $ prettyPrint p
+    Left e -> putStrLn $ show e
+
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright Dmitry Golubovsky 2008.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Dmitry Golubovsky nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Language/WebIDL.hs b/Language/WebIDL.hs
new file mode 100644
--- /dev/null
+++ b/Language/WebIDL.hs
@@ -0,0 +1,27 @@
+------------------------------------------------------------------
+-- |
+-- Module      :  Language.WebIDL
+-- Copyright   :  (c) Dmitry Golubovsky, 2009
+-- License     :  BSD-style
+-- 
+-- Maintainer  :  golubovsky@gmail.com
+-- Stability   :  experimental
+-- Portability :  portable
+-- 
+--
+--
+-- Re-export commonly used modules.
+------------------------------------------------------------------
+
+module Language.WebIDL (
+  module Language.WebIDL.Syntax
+ ,module Language.WebIDL.Lexer
+ ,module Language.WebIDL.PrettyPrint
+ ,module Language.WebIDL.Parser) where
+
+import Language.WebIDL.Syntax
+import Language.WebIDL.Parser
+import Language.WebIDL.PrettyPrint
+import Language.WebIDL.Lexer
+
+       
diff --git a/Language/WebIDL/Lexer.hs b/Language/WebIDL/Lexer.hs
new file mode 100644
--- /dev/null
+++ b/Language/WebIDL/Lexer.hs
@@ -0,0 +1,78 @@
+------------------------------------------------------------------
+-- |
+-- Module      :  Language.WebIDL.Lexer
+-- Copyright   :  (c) Dmitry Golubovsky, 2009
+-- License     :  BSD-style
+-- 
+-- Maintainer  :  golubovsky@gmail.com
+-- Stability   :  experimental
+-- Portability :  portable
+-- 
+--
+--
+-- FFI access to the WebIDL lexer from the es-operating-system project.
+------------------------------------------------------------------
+
+module Language.WebIDL.Lexer (
+  Token (..)
+ ,pickToken
+ ,lexStdin) where
+
+
+import HS_LEXER_H
+import Control.Monad
+import Data.ByteString (ByteString(..), packCString)
+import Data.ByteString.UTF8 (toString)
+
+-- |Data type to represent IDL tokens.
+
+data Token = Token {
+  tag :: Int                     -- ^whatever yylex() returns
+ ,line :: Int                    -- ^starting line
+ ,column:: Int                   -- ^starting column
+ ,name :: String                 -- ^token value or an empty string
+} deriving (Show)
+
+fromIntegralM = return . fromIntegral
+
+tokValue :: IO String
+
+tokValue = do
+  tok <- v_p_yylval
+  nm <- tok --> V_name
+  if nm == nullPtr 
+    then return ""
+    else do
+      s <- packCString nm >>= return . toString
+      f_free nm
+      (tok, V_name) <-- nullPtr
+      return s
+
+-- |Get a token from the lexer. Upon EOF, token with tag 0 will be returned.
+
+pickToken :: IO Token
+
+pickToken = do
+  tag <- f_yylex
+  loc <- v_p_yylloc
+  line <- loc --> V_first_line
+  column <- loc --> V_first_column
+  return Token `ap` fromIntegralM tag 
+               `ap` fromIntegralM line 
+               `ap` fromIntegralM column 
+               `ap` tokValue
+
+
+-- |Tokenize the standard input.
+
+lexStdin :: IO [Token]
+
+lexStdin = lsin [] where
+  lsin ts = do
+    t <- pickToken
+    let ts' = t:ts
+    case tag t of
+      0 -> return (reverse ts')
+      _ -> lsin ts'
+
+
diff --git a/Language/WebIDL/Parser.hs b/Language/WebIDL/Parser.hs
new file mode 100644
--- /dev/null
+++ b/Language/WebIDL/Parser.hs
@@ -0,0 +1,497 @@
+------------------------------------------------------------------
+-- |
+-- Module      :  Language.WebIDL.Parser
+-- Copyright   :  (c) Dmitry Golubovsky, 2009
+-- License     :  BSD-style
+-- 
+-- Maintainer  :  golubovsky@gmail.com
+-- Stability   :  experimental
+-- Portability :  portable
+-- 
+--
+--
+-- Parser of the tokenized IDL.
+------------------------------------------------------------------
+
+module Language.WebIDL.Parser (
+  parseIDL) where
+
+import Data.Char
+import HS_LEXER_H
+import Text.ParserCombinators.Parsec
+import Text.ParserCombinators.Parsec.Pos
+import Text.ParserCombinators.Parsec.Expr
+import Language.WebIDL.Lexer
+import Language.WebIDL.Syntax
+import Control.Monad
+
+type IDLParser a = GenParser Token () a
+
+-- |Run the parser, return IDL definitions.
+
+parseIDL :: [Token] -> Either ParseError IDLSpecification
+
+parseIDL tks = runParser specification () "" tks where
+
+specification = do
+  ss <- many definition
+  tokEOF
+  return (filter nodefpp ss)
+
+nodefpp (IDLDefinition _ _ IDLDefPP) = False
+nodefpp _ = True
+
+definition = do
+  jd <- try javadoc
+  pos <- getPosition
+  df <- definition'
+  return $ IDLDefinition pos jd df
+
+definition' =
+  try (withSemi def_module) <|>
+  try def_interface <|>
+  try (withSemi except_dcl >>= return . IDLDefExcept) <|>
+  try (withSemi type_dcl >>= return . IDLDefType) <|>
+  try (withSemi const_dcl >>= return . IDLDefConst) <|>
+  try (withSemi value_dcl) <|>
+  try (preprocessor >> return IDLDefPP)
+
+def_module = do
+  os <- option [] (try extended_attribute_list)
+  tokMODULE
+  i <- tokIDENTIFIER >>= return . name
+  dfs <- curlies (many definition)
+  return $ IDLDefModule i os dfs
+
+javadoc = option "" (try (tokJAVADOC >>= return . name)) >>= return . JavaDoc
+
+def_interface = do
+  i <- (try interface_dcl <|> try forward_dcl)
+  tokSemi
+  return i
+
+except_dcl = do
+  tokEXCEPTION
+  ei <- tokIDENTIFIER >>= return . name
+  ml <- curlies (many member)
+  return $ IDLExceptDcl ei ml
+
+forward_dcl = do
+  tokINTERFACE
+  ii <- tokIDENTIFIER >>= return . name
+  return $ IDLDefInterface ii [] [] Nothing
+
+interface_dcl = do
+  h <- interface_header
+  b <- curlies interface_body
+  return $ h $ Just b
+
+interface_header = do
+  eas <- option [] (try extended_attribute_list)
+  tokINTERFACE
+  ii <- tokIDENTIFIER >>= return . name
+  inhr <- option [] (try interface_inheritance_spec)
+  return $ IDLDefInterface ii eas inhr
+
+interface_body = do
+  es <- many export
+  return $ IDLInterfaceBody (filter noexppp es)
+
+noexppp (IDLExport _ _ IDLExpPP) = False
+noexppp _ = True
+
+export = do
+  jd <- javadoc
+  pos <- getPosition
+  ex <- export'
+  return $ IDLExport pos jd ex
+
+export' = 
+  try (withSemi type_dcl >>= return . IDLExpType) <|>
+  try (withSemi except_dcl >>= return . IDLExpExcept) <|>
+  try (withSemi attr_dcl >>= return . IDLExpAttr) <|>
+  try (withSemi op_dcl >>= return . IDLExpOp) <|>
+  try (withSemi const_dcl >>= return . IDLExpConst) <|>
+  try (preprocessor >> return IDLExpPP)
+
+type_dcl =
+  try tdnative <|> 
+  try (struct_type >>= return . IDLStruct) <|>
+  try tdtypedef <|>
+  try (tokSTRUCT >> tokIDENTIFIER >>= return . IDLConstrFwd . name) <?>
+  "type declaration"
+
+value_dcl = do
+  tokVALUETYPE
+  vi <- tokIDENTIFIER >>= return . name
+  mt <- option Nothing (try type_spec >>= return . Just)
+  return $ IDLDefValue vi mt
+
+tdnative = do
+  tokNATIVE
+  tn <- tokIDENTIFIER >>= return . name
+  return $ IDLNative tn
+
+tdtypedef = do
+  tokTYPEDEF
+  ts <- type_spec
+  ds <- (declarator `sepBy1` tokComma)
+  return $ IDLTypeDef ts ds
+
+op_dcl = do
+  eas <- option [] (try extended_attribute_list)
+  oao <- option Nothing (try tokONEWAY >> return (Just IDLOneWay))
+  ots <- op_type_spec
+  oi <- tokIDENTIFIER >>= return . name
+  pds <- parameter_dcls
+  rsx <- option [] (try raises_expr)
+  return $ IDLOpDcl eas oao ots oi pds rsx
+
+raises_expr = tokRAISES >> parens (scoped_name `sepBy1` tokComma) 
+
+interface_inheritance_spec = do
+  tokColon
+  scoped_name `sepBy1` tokComma
+
+op_type_spec =
+  try param_type_spec <|>
+  try (tokVOID >> return IDLParamVoid) <?>
+  "operation type specification"
+
+param_type_spec =
+  try (scoped_name >>= return . IDLParamScopedSpec) <|>
+  try (base_type_spec >>= return . IDLParamBaseSpec) <|>
+  try (string_type >>= return . IDLParamStringSpec) <?>
+  "parameter type specification"
+
+simple_type_spec =
+  try (scoped_name >>= return . IDLSimpleScoped) <|>
+  try (base_type_spec >>= return . IDLSimpleBase) <|>
+  try (template_type_spec >>= return . IDLSimpleTmpl) <?>
+  "simple type specification"
+
+base_type_spec =
+  try (floating_pt_type >>= return . IDLBaseTypeFloat) <|>
+  try (integer_type >>= return . IDLBaseTypeInt) <|>
+  try (tokCHAR >> return IDLBaseTypeChar) <|>
+  try (tokBOOLEAN >> return IDLBaseTypeBool) <|>
+  try (tokOCTET >> return IDLBaseTypeOctet) <|>
+  try (tokANY >> return IDLBaseTypeAny)
+
+template_type_spec =
+  try (sequence_type >>= return . IDLTmplSequence) <|>
+  try (string_type >>= return . IDLTmplString) <|>
+  try (fixed_pt_type >>= return . IDLTmplFixed)
+
+floating_pt_type =
+  try (tokLONG >> tokDOUBLE >> return IDLLongDouble) <|>
+  try (tokFLOAT >> return IDLFloat) <|>
+  try (tokDOUBLE >> return IDLDouble) <?>
+  "floating point type"
+
+sequence_type = do
+  tokSEQUENCE
+  angles $ do
+    st <- simple_type_spec
+    mbc <- option Nothing (tokComma >> const_exp >>= return . Just)
+    return $ IDLSequenceType st mbc
+
+fixed_pt_type = do
+  tokFIXED
+  angles $ do
+    c1 <- const_exp
+    c2 <- const_exp
+    return $ IDLFixedType c1 c2
+
+integer_type = do
+  sus <- option IDLSigned (try (tokUNSIGNED >> return IDLUnsigned))
+  it <- try (tokSHORT >> return IDLShortInt) <|>
+        try (tokLONG >> tokLONG >> return IDLLongLongInt) <|>
+        try (tokLONG >> return IDLLongInt) <?>
+        "integer type"
+  return $ sus it
+
+scoped_name = do
+  ns <- (tokIDENTIFIER >>= return . name) `sepBy1` tokOP_SCOPE
+  return $ IDLScopedName ns
+
+extended_attribute_list = brackets (extended_attribute `sepBy1` tokComma)
+
+extended_attribute = do
+  jd <- javadoc
+  ai <- tokIDENTIFIER >>= return . name
+  ds <- option Nothing (extended_attribute_details >>= return . Just)
+  return $ IDLExtAttr jd ai ds
+
+extended_attribute_details =
+  try eadid <|>
+  try eadsn <|>
+  try (parameter_dcls >>= return . IDLDetailPD)
+
+eadsn = do
+  tokEq
+  sn <- scoped_name
+  return $ IDLDetailSN sn
+
+eadid = do
+  tokEq
+  ei <- tokIDENTIFIER >>= return . name
+  pds <- parameter_dcls
+  return $ IDLDetailID ei pds
+
+parameter_dcls = parens (param_dcl `sepBy` tokComma)  
+
+param_dcl = do
+  eas <- option [] (try extended_attribute_list)
+  pa <- param_attribute
+  pt <- param_type_spec
+  pi <- tokIDENTIFIER >>= return . name
+  return $ IDLParamDcl eas pa pt pi
+
+param_attribute =
+  try (tokIN >> return IDLParamIn) <|>
+  try (tokOUT >> return IDLParamOut) <|>
+  try (tokINOUT >> return IDLParamInOut)
+
+member = do
+  ts <- type_spec
+  ds <- (declarator `sepBy1` tokComma)
+  tokSemi
+  return $ IDLMember ts ds
+
+type_spec =
+  try (simple_type_spec >>= return . IDLSimpleSpec) <|>
+  try (struct_type >>= return . IDLStructSpec)
+
+struct_type = do
+  tokSTRUCT
+  si <- tokIDENTIFIER >>= return . name
+  ml <- curlies (many member)
+  return $ IDLStructType si ml
+
+string_type = do
+  tokSTRING
+  sl <- option Nothing (angles const_exp >>= return . Just)
+  return $ IDLStringType sl
+
+declarator =
+  try (array_declarator >>= return . IDLComplexDecl) <|>
+  try (simple_declarator >>= return . IDLSimpleDecl) <?>
+  "declarator"
+
+array_declarator = do
+  ai <- tokIDENTIFIER >>= return . name
+  dims <- many1 fixed_array_size
+  return $ IDLArrayDeclarator ai dims
+
+fixed_array_size = brackets const_exp
+
+attr_dcl = do
+  os <- option [] (try extended_attribute_list)
+  ro <- option False (try (tokREADONLY >> return True))
+  tokATTRIBUTE
+  ps <- param_type_spec
+  ai <- tokIDENTIFIER >>= return . name
+  gx <- x_excep_expr tokGETRAISES
+  sx <- x_excep_expr tokSETRAISES
+  return $ IDLAttrDcl os ro ps ai gx sx
+
+x_excep_expr tok = option [] $ try $ do
+  tok
+  parens (scoped_name `sepBy1` tokComma)
+  
+const_dcl = do
+  tokCONST
+  ct <- const_type
+  ci <- tokIDENTIFIER >>= return . name
+  tokEq
+  cc <- const_exp
+  return $ IDLConstDcl ct ci cc  
+
+const_type =
+  try (floating_pt_type >>= return . IDLConstTypeFloat) <|>
+  try (integer_type >>= return . IDLConstTypeInt) <|>
+  try (tokCHAR >> return IDLConstTypeChar) <|>
+  try (tokBOOLEAN >> return IDLConstTypeBool) <|>
+  try (tokOCTET >> return IDLConstTypeOctet) <|>
+  try (scoped_name >>= return . IDLConstTypeScoped) <|>
+  try (string_type >>= return . IDLConstTypeString) <|>
+  try (tokFIXED >> return IDLConstTypeFixed)
+  
+const_exp = buildExpressionParser optable primary_expr
+
+optable = [ [pfxc '-' IDLNeg, pfxc '+' IDLPos, pfxc '~' IDLNot]
+           ,[binc '*' IDLMult AssocLeft, binc '/' IDLDiv AssocLeft, binc '%' IDLRem AssocLeft]
+           ,[binc '+' IDLAdd AssocLeft, binc '-' IDLSub AssocLeft]
+           ,[binary tokOP_SHL IDLShiftL AssocLeft, binary tokOP_SHR IDLShiftR AssocLeft]
+           ,[binc '&' IDLAnd AssocLeft]
+           ,[binc '^' IDLXor AssocLeft]
+           ,[binc '|' IDLOr AssocLeft]
+          ]
+
+binary tok ctor assoc = Infix  (tok >> return (IDLBinExp ctor)) assoc
+prefix tok ctor       = Prefix (tok >> return (IDLUnaryExp ctor))
+pfxc c = prefix (tokChar c)
+binc c = binary (tokChar c)
+
+
+primary_expr =
+  try (scoped_name >>= return . IDLPrimScoped) <|>
+  try (parens const_exp >>= return . IDLParenExp) <|>
+  try (literal >>= return . IDLPrimLit)
+
+literal = 
+  try (tokVal c_INTEGER_LITERAL "<integer>" >>= return . IDLIntLit) <|>
+  try (tokVal c_STRING_LITERAL "<string>" >>= return . IDLStringLit) <|>
+  try (tokVal c_CHARACTER_LITERAL "<char>" >>= return . IDLCharLit) <|>
+  try (tokVal c_FIXED_PT_LITERAL "<fixed>" >>= return . IDLFixedLit) <|>
+  try (tokVal c_FLOATING_PT_LITERAL "<float>" >>= return . IDLFloatLit) <|>
+  try (tokTRUE >> return (IDLBoolLit "TRUE")) <|>
+  try (tokFALSE >> return (IDLBoolLit "FALSE")) <?>
+  "literal"
+
+simple_declarator = tokIDENTIFIER >>= return . name
+
+-- Preprocessor directives: ignore everything between pound-sign and EOL.
+-- Sometimes the last line contains #endif, and then EOF without EOL.
+-- For this case, both EOL and EOF are checked, and if EOF is encountered,
+-- it is returned for reprocessing, but EOL is simulated.
+
+preprocessor = do
+  tokPOUND_SIGN
+  manyTill anyToken eol_eof
+
+eol_eof =
+  try (tokEOL >> return tokEOL) <|>
+  try (do t <- tokEOF
+          setInput [t] 
+          return tokEOL)
+
+-- Tokens from the lexer
+
+tokPos t = newPos "" (line t) (column t)
+
+-- Universal token tester.
+
+tokTok :: Integral n => n -> String -> IDLParser Token
+
+tokTok n s = token (const s) tokPos isn <?> s where
+  isn t = if (fromIntegral n) == tag t then (Just t) else Nothing
+
+-- One-character token.
+
+tokChar :: Char -> IDLParser Char
+
+tokChar c = token (const [c]) tokPos (isc c) <?> [c] where
+  isc c t = if (ord c) == tag t then (Just c) else Nothing
+
+-- A token whose value has to be retrieved.
+
+tokVal :: Integral n => n -> String -> IDLParser String
+
+tokVal n s = tokTok n s >>= return . name
+
+-- Token primitives. They pass when a token specified is encountered, fail otherwise.
+
+tokEOF = tokTok 0 "<eof>"
+
+tokMODULE = tokTok c_MODULE "module"
+
+tokJAVADOC = tokTok c_JAVADOC "/** javadoc */"
+
+tokIDENTIFIER = tokTok c_IDENTIFIER "identifier"
+
+tokINTERFACE = tokTok c_INTERFACE "interface"
+
+tokOP_SCOPE = tokTok c_OP_SCOPE "::"
+
+tokTYPEDEF = tokTok c_TYPEDEF "typedef"
+
+tokNATIVE = tokTok c_NATIVE "native"
+
+tokONEWAY = tokTok c_ONEWAY "oneway"
+
+tokRAISES = tokTok c_RAISES "raises"
+
+tokVOID = tokTok c_VOID "void"
+
+tokIN = tokTok c_IN "in"
+
+tokOUT = tokTok c_OUT "out"
+
+tokINOUT = tokTok c_INOUT "inout"
+
+tokEXCEPTION = tokTok c_EXCEPTION "exception"
+
+tokSTRUCT = tokTok c_STRUCT "struct"
+
+tokCHAR = tokTok c_CHAR "char"
+
+tokBOOLEAN = tokTok c_BOOLEAN "boolean"
+
+tokOCTET = tokTok c_OCTET "octet"
+
+tokANY = tokTok c_ANY "any"
+
+tokLONG = tokTok c_LONG "long"
+
+tokFLOAT = tokTok c_FLOAT "float"
+
+tokDOUBLE = tokTok c_DOUBLE "double"
+
+tokUNSIGNED = tokTok c_UNSIGNED "unsigned"
+
+tokSHORT = tokTok c_SHORT "short"
+
+tokREADONLY = tokTok c_READONLY "readonly"
+
+tokATTRIBUTE = tokTok c_ATTRIBUTE "attribute"
+
+tokGETRAISES = tokTok c_GETRAISES "getraises"
+
+tokSETRAISES = tokTok c_SETRAISES "setraises"
+
+tokCONST = tokTok c_CONST "const"
+
+tokFIXED = tokTok c_FIXED "const"
+
+tokSTRING = tokTok c_STRING "string"
+
+tokOP_SHR = tokTok c_OP_SHR ">>"
+
+tokOP_SHL = tokTok c_OP_SHL "<<"
+
+tokTRUE = tokTok c_TRUE "True"
+
+tokFALSE = tokTok c_FALSE "False"
+
+tokSEQUENCE = tokTok c_SEQUENCE "sequence"
+
+tokVALUETYPE = tokTok c_VALUETYPE "valuetype"
+
+tokPOUND_SIGN = tokTok c_POUND_SIGN "#"
+
+tokEOL = tokTok c_EOL "<eol>"
+
+tokSemi = tokChar ';'
+
+tokColon = tokChar ':'
+
+tokComma = tokChar ','
+
+tokEq = tokChar '='
+
+-- Various utilities
+
+curlies = between (tokChar '{') (tokChar '}')
+
+brackets = between (tokChar '[') (tokChar ']')
+
+parens = between (tokChar '(') (tokChar ')')
+
+angles = between (tokChar '<') (tokChar '>')
+
+withSemi p = do
+  x <- p
+  tokSemi
+  return x
diff --git a/Language/WebIDL/PrettyPrint.hs b/Language/WebIDL/PrettyPrint.hs
new file mode 100644
--- /dev/null
+++ b/Language/WebIDL/PrettyPrint.hs
@@ -0,0 +1,209 @@
+------------------------------------------------------------------
+-- |
+-- Module      :  Language.WebIDL.PrettyPrint
+-- Copyright   :  (c) Dmitry Golubovsky, 2009
+-- License     :  BSD-style
+-- 
+-- Maintainer  :  golubovsky@gmail.com
+-- Stability   :  experimental
+-- Portability :  portable
+-- 
+--
+--
+-- Pretty printer for the IDL parsed syntax.
+------------------------------------------------------------------
+
+module Language.WebIDL.PrettyPrint (prettyPrint) where
+
+import Data.Maybe
+import Text.PrettyPrint.HughesPJ
+import Language.WebIDL.Syntax
+
+-- |Pretty print a parsed IDL specification.
+
+prettyPrint :: IDLSpecification -> String
+
+prettyPrint = render . prSpec
+
+prSpec s = vcat (map prDef s)
+
+prDef (IDLDefinition pos jd def) = vcat [prJd jd, prDef' def] <> semi
+
+prJd (JavaDoc "") = empty
+prJd (JavaDoc tx) = text tx
+
+
+prDef' (IDLDefModule mn xattr defs) =
+  prXattr xattr <+> text "module" <+> text mn <+> lbrace $+$ 
+    (nest 2 $ prSpec defs) $+$ rbrace
+prDef' (IDLDefInterface ii _ _ Nothing) =
+  text "interface" <+> text ii
+prDef' (IDLDefInterface ii xattr inhr (Just ib)) =
+  prXattr xattr <+> text "interface" <+> text ii <+> prInhr inhr <+> lbrace $+$
+    (nest 2 $ prIbody ib) $+$ rbrace
+prDef' (IDLDefType td) = prTypeDcl td
+prDef' (IDLDefExcept ex) = prExcept ex
+prDef' (IDLDefConst cn) = prConst cn
+prDef' (IDLDefValue iv Nothing) = text "valuetype" <+> text iv
+prDef' (IDLDefValue iv (Just ts)) = text "valuetype" <+> text iv <+> prTypeSpec ts
+prDef'  IDLDefPP = empty
+
+prInhr [] = empty
+prInhr sns = colon <+> hsep (punctuate comma (map prScoped sns))
+
+prScoped (IDLScopedName ns) = hsep $ punctuate (space <> colon <> colon) (map text ns)
+
+prIbody (IDLInterfaceBody exps) = vcat (map prExport exps)
+
+prXattr [] = empty
+
+prXattr as = brackets $ hsep $ punctuate comma (map prXattr' as)
+
+prXattr' (IDLExtAttr jd ai mbds) = prJd jd $$ (text ai <> prMbds mbds)
+
+prMbds Nothing = empty
+prMbds (Just (IDLDetailSN sn)) = space <> equals <+> prScoped sn
+prMbds (Just (IDLDetailID di pdcls)) = space <> equals <+> text di <> prParamDcls pdcls
+prMbds (Just (IDLDetailPD pdcls)) = prParamDcls pdcls
+
+prExport (IDLExport pos jd exp) = vcat [prJd jd, prExport' exp] <> semi
+
+prExport' (IDLExpType td) = prTypeDcl td
+prExport' (IDLExpExcept ex) = prExcept ex
+prExport' (IDLExpConst cn) = prConst cn
+prExport' (IDLExpAttr at) = prAttr at
+prExport' (IDLExpOp op) = prOp op
+prExport'  IDLExpPP = empty
+
+prOp (IDLOpDcl xattr mbow pts oi pdcls sns) =
+  prXattr xattr <+> prOpAttr mbow <+> prParamTypeSpec pts <+> text oi <>
+          prParamDcls pdcls <+> prExcList "raises" sns
+
+prOpAttr Nothing = empty
+prOpAttr (Just IDLOneWay) = text "oneway"
+
+prParamDcls [] = parens empty
+prParamDcls pdcls = parens (hsep (punctuate comma (map prParam pdcls)))
+
+prParam (IDLParamDcl xattr pattr pts pi) =
+  prXattr xattr <+> prPattr pattr <+> prParamTypeSpec pts <+> text pi
+
+prPattr IDLParamIn = text "in"
+prPattr IDLParamOut = text "out"
+prPattr IDLParamInOut = text "inout"
+
+prAttr (IDLAttrDcl xattr ro pts ai getx setx) =
+  prXattr xattr <+> (if ro then text "readonly" else empty) <+> text "attribute" <+>
+          prParamTypeSpec pts <+> text ai <+> 
+          prExcList "getraises" getx <+> prExcList "setraises" setx
+
+prParamTypeSpec (IDLParamBaseSpec sb) = prBaseTypeSpec sb
+prParamTypeSpec (IDLParamStringSpec st) = prStringType st
+prParamTypeSpec (IDLParamScopedSpec sn) = prScoped sn
+prParamTypeSpec  IDLParamVoid = text "void"
+
+prExcList kw [] = empty
+prExcList kw excs = text kw <+> parens (hsep (punctuate comma (map prScoped excs)))
+
+prConst (IDLConstDcl ct ci ex) = 
+  text "const" <+> prConstType ct <+> text ci <+> equals <+> prExpr ex
+
+prConstType (IDLConstTypeFloat fl) = prFloatType fl
+prConstType (IDLConstTypeInt it) = prIntType it
+prConstType (IDLConstTypeString st) = prStringType st
+prConstType  IDLConstTypeChar = text "char"
+prConstType  IDLConstTypeBool = text "boolean"
+prConstType  IDLConstTypeFixed = text "fixed"
+prConstType  IDLConstTypeOctet = text "octet"
+prConstType (IDLConstTypeScoped sn) = prScoped sn
+
+prBaseTypeSpec (IDLBaseTypeFloat fl) = prFloatType fl
+prBaseTypeSpec (IDLBaseTypeInt it) = prIntType it
+prBaseTypeSpec  IDLBaseTypeChar = text "char"
+prBaseTypeSpec  IDLBaseTypeBool = text "boolean"
+prBaseTypeSpec  IDLBaseTypeOctet = text "octet"
+prBaseTypeSpec  IDLBaseTypeAny = text "any"
+
+prFloatType IDLFloat = text "float"
+prFloatType IDLDouble = text "double"
+prFloatType IDLLongDouble = text "long double"
+
+prIntType (IDLSigned ii) = prIntType' ii
+prIntType (IDLUnsigned ii) = text "unsigned" <+> prIntType' ii
+
+prIntType' IDLShortInt = text "short"
+prIntType' IDLLongInt = text "long"
+prIntType' IDLLongLongInt = text "long long"
+
+prStringType (IDLStringType Nothing) = text "string"
+prStringType (IDLStringType (Just ex)) = text "string <" <> prExpr ex <> text ">"
+
+prTypeDcl (IDLNative s) = text "native" <+> text s
+prTypeDcl (IDLConstrFwd s) = text "struct" <+> text s
+prTypeDcl (IDLTypeDef its ds) = text "typedef" <+> prTypeSpec its <+> prDecls ds
+prTypeDcl (IDLStruct st) = prStruct st
+
+prStruct (IDLStructType si mbs) = prMembers "struct" si mbs
+
+prExcept (IDLExceptDcl ei mbs) = prMembers "exception" ei mbs
+
+prMembers kw ii mbs = text kw <+> text ii <+> lbrace $+$ nest 2 (vcat (map prMember mbs)) $+$ rbrace
+
+prMember (IDLMember its ds) = prTypeSpec its <+> prDecls ds <> semi
+
+prTypeSpec (IDLSimpleSpec sts) = prSimpleTypeSpec sts
+prTypeSpec (IDLStructSpec str) = prStruct str
+
+prSimpleTypeSpec (IDLSimpleBase sb) = prBaseTypeSpec sb
+prSimpleTypeSpec (IDLSimpleTmpl st) = prTmplTypeSpec st
+prSimpleTypeSpec (IDLSimpleScoped sn) = prScoped sn
+
+prTmplTypeSpec (IDLTmplSequence sq) = prSequence sq
+prTmplTypeSpec (IDLTmplString st) = prStringType st
+prTmplTypeSpec (IDLTmplFixed fx) = prFixedType fx
+
+prSequence (IDLSequenceType ts Nothing) = text "sequence <" <> prSimpleTypeSpec ts <> text ">"
+prSequence (IDLSequenceType ts (Just ex)) = 
+  text "sequence <" <> prSimpleTypeSpec ts <> comma <+> prExpr ex <> text ">"
+
+prFixedType (IDLFixedType ex1 ex2) = 
+  text "fixed <" <> prExpr ex1 <> comma <+> prExpr ex2 <> text ">"
+
+prDecl (IDLSimpleDecl s) = text s
+prDecl (IDLComplexDecl iad) = prArray iad
+
+prArray (IDLArrayDeclarator ai dims) = text ai <+> prDims dims
+
+prDims [] = empty
+prDims (d:ds) = lbrack <> prExpr d <> rbrack <> prDims ds
+
+prDecls ds = hsep (punctuate comma (map prDecl ds))
+
+prExpr (IDLParenExp ex) = parens (prExpr ex)
+prExpr (IDLPrimScoped sn) = prScoped sn
+prExpr (IDLPrimLit lit) = prLit lit
+prExpr (IDLBinExp op l r) = prExpr l <+> prBin op <+> prExpr r
+prExpr (IDLUnaryExp op e) = prUn op <> prExpr e
+
+prBin IDLOr = text "|"
+prBin IDLXor = text "^"
+prBin IDLAnd = text "&"
+prBin IDLShiftL = text "<<"
+prBin IDLShiftR = text ">>"
+prBin IDLAdd = text "+"
+prBin IDLSub = text "-"
+prBin IDLMult = text "*"
+prBin IDLDiv = text "/"
+prBin IDLRem = text "%"
+
+prUn IDLPos = empty
+prUn IDLNeg = text "-"
+prUn IDLNot = text "~"
+
+prLit (IDLIntLit s) = text s
+prLit (IDLStringLit s) = text s
+prLit (IDLCharLit s) = text s
+prLit (IDLFixedLit s) = text s
+prLit (IDLFloatLit s) = text s
+prLit (IDLBoolLit s) = text s
+
diff --git a/Language/WebIDL/Syntax.hs b/Language/WebIDL/Syntax.hs
new file mode 100644
--- /dev/null
+++ b/Language/WebIDL/Syntax.hs
@@ -0,0 +1,438 @@
+------------------------------------------------------------------
+-- |
+-- Module      :  Language.WebIDL.Syntax
+-- Copyright   :  (c) Dmitry Golubovsky, 2009
+-- License     :  BSD-style
+-- 
+-- Maintainer  :  golubovsky@gmail.com
+-- Stability   :  experimental
+-- Portability :  portable
+-- 
+--
+--
+-- Web IDL syntax representation. It is built based on the original
+-- yacc/bison parser found in the es-operating-system project. 
+-- The source of the original parser (written in C++) is located here:
+--
+-- <http://es-operating-system.googlecode.com/svn/trunk/esidl/src/parser.yy>
+--------------------------------------------------------------------
+
+module Language.WebIDL.Syntax where
+
+import Data.Maybe
+import Text.ParserCombinators.Parsec.Pos
+
+-- specification : | definition_list
+
+type IDLSpecification = [IDLDefinition]
+
+newtype JavaDoc = JavaDoc String deriving (Show)
+
+data IDLDefinition = IDLDefinition SourcePos JavaDoc IDLDef deriving (Show)
+
+-- definition :
+--    module ';'
+--    | interface ';'
+--    | except_dcl ';'
+--    | type_dcl ';'
+--    | value ';'
+--    | const_dcl ';'
+--    | preprocessor
+    
+data IDLDef = 
+-- module :
+--    extended_attribute_opt MODULE IDENTIFIER
+--   '{' definition_list '}'
+   IDLDefModule String [IDLExtAttr] [IDLDefinition]
+
+-- interface :
+--   interface_dcl
+--   | forward_dcl
+-- interface_dcl :
+--   interface_header '{' interface_body '}'
+-- interface_header :
+--   INTERFACE IDENTIFIER interface_inheritance_spec
+--   | INTERFACE IDENTIFIER
+--   | extended_attribute_list INTERFACE IDENTIFIER interface_inheritance_spec
+--   | extended_attribute_list INTERFACE IDENTIFIER
+-- value :
+--   value_box_dcl
+--   | value_forward_dcl
+-- value_forward_dcl :
+--   VALUETYPE IDENTIFIER
+-- value_box_dcl :
+--   VALUETYPE IDENTIFIER type_spec
+
+ | IDLDefInterface String [IDLExtAttr] [IDLScopedName] (Maybe IDLInterfaceBody)
+ | IDLDefExcept IDLExceptDcl
+ | IDLDefType IDLTypeDcl
+ | IDLDefConst IDLConstDcl
+ | IDLDefValue String (Maybe IDLTypeSpec)
+ | IDLDefPP
+ deriving (Show)
+
+-- scoped_name :
+--   IDENTIFIER
+--   | OP_SCOPE IDENTIFIER
+--   | scoped_name OP_SCOPE IDENTIFIER
+
+data IDLScopedName = IDLScopedName [String] deriving (Show)
+
+-- extended_attribute_opt :
+--   | extended_attribute_list
+-- extended_attribute_list :
+--    '[' extended_attributes ']'
+-- extended_attributes :
+--   extended_attribute
+--   | extended_attributes ',' extended_attribute
+-- extended_attribute :
+--     javadoc IDENTIFIER extended_attribute_details
+
+data IDLExtAttr = IDLExtAttr JavaDoc String (Maybe IDLExtAttrDetails) deriving (Show)
+
+-- extended_attribute_details :
+--   | '=' scoped_name
+--   | '=' IDENTIFIER  parameter_dcls
+--   | parameter_dcls
+
+data IDLExtAttrDetails = 
+   IDLDetailSN IDLScopedName
+ | IDLDetailID String [IDLParamDcl]
+ | IDLDetailPD [IDLParamDcl]
+  deriving (Show)
+
+-- simple_declarator :
+--    IDENTIFIER
+
+-- param_attribute :
+--   IN
+--   | OUT
+--   | INOUT
+
+data IDLParamAttr = 
+   IDLParamIn
+ | IDLParamOut
+ | IDLParamInOut
+  deriving (Show)
+
+-- param_type_spec :
+--   base_type_spec
+--   | string_type
+--   | scoped_name
+
+data IDLParamTypeSpec = 
+   IDLParamBaseSpec IDLBaseTypeSpec
+ | IDLParamStringSpec IDLStringType
+ | IDLParamScopedSpec IDLScopedName
+ | IDLParamVoid                              -- to be also used with op_type_spec
+  deriving (Show)
+
+-- base_type_spec :
+--   floating_pt_type
+--   | integer_type
+--   | char_type
+--   | boolean_type
+--   | octet_type
+--   | any_type
+
+data IDLBaseTypeSpec = 
+   IDLBaseTypeFloat IDLFloatingType
+ | IDLBaseTypeInt IDLIntegerType
+ | IDLBaseTypeChar
+ | IDLBaseTypeBool
+ | IDLBaseTypeOctet
+ | IDLBaseTypeAny
+  deriving (Show)
+
+-- floating_pt_type :
+--   FLOAT
+--   | DOUBLE
+--   | LONG DOUBLE
+
+data IDLFloatingType = 
+   IDLFloat
+ | IDLDouble
+ | IDLLongDouble
+  deriving (Show)
+
+-- integer_type :
+--    signed_int
+--    | unsigned_int
+-- signed_int :
+--    signed_short_int
+--    | signed_long_int
+--    | signed_longlong_int
+-- signed_short_int :
+--    SHORT
+-- signed_long_int :
+--    LONG
+-- signed_longlong_int :
+--    LONG LONG
+-- unsigned_int :
+--    unsigned_short_int
+--    | unsigned_long_int
+--    | unsigned_longlong_int
+-- unsigned_short_int :
+--    UNSIGNED SHORT
+-- unsigned_long_int :
+--    UNSIGNED LONG
+-- unsigned_longlong_int :
+--    UNSIGNED LONG LONG
+
+data IDLIntegerType =
+   IDLSigned IDLInteger
+ | IDLUnsigned IDLInteger
+  deriving (Show)
+
+data IDLInteger =
+   IDLShortInt
+ | IDLLongInt
+ | IDLLongLongInt
+  deriving (Show)
+
+-- interface_body :
+--   export_list_opt
+-- export_list_opt :
+--   /* empty */
+--   | export_list
+
+data IDLInterfaceBody = IDLInterfaceBody [IDLExport] deriving (Show)
+
+-- export_list :
+--   javadoc export
+--   | export_list javadoc export
+
+data IDLExport = IDLExport SourcePos JavaDoc IDLExp deriving (Show)
+
+-- export :
+--   type_dcl ';'
+--   | const_dcl ';'
+--   | except_dcl ';'
+--   | attr_dcl ';'
+--   | op_dcl ';'
+--   | preprocessor
+
+data IDLExp = 
+   IDLExpType IDLTypeDcl
+ | IDLExpConst IDLConstDcl
+ | IDLExpExcept IDLExceptDcl
+ | IDLExpAttr IDLAttrDcl
+ | IDLExpOp   IDLOpDcl
+ | IDLExpPP
+  deriving (Show)
+
+-- type_dcl :
+--   TYPEDEF type_declarator
+--   | struct_type
+--   | NATIVE simple_declarator
+--   | constr_forward_decl
+
+data IDLTypeDcl =
+   IDLTypeDef IDLTypeSpec [IDLDeclarator]
+ | IDLNative String
+ | IDLStruct IDLStructType
+ | IDLConstrFwd String
+  deriving (Show)
+
+-- type_spec :
+--   simple_type_spec
+--   | struct_type
+
+data IDLTypeSpec =
+   IDLSimpleSpec IDLSimpleTypeSpec
+ | IDLStructSpec IDLStructType
+  deriving (Show)
+
+-- simple_type_spec :
+--   base_type_spec
+--   | template_type_spec
+--   | scoped_name
+
+data IDLSimpleTypeSpec =
+   IDLSimpleBase IDLBaseTypeSpec
+ | IDLSimpleTmpl IDLTemplateTypeSpec
+ | IDLSimpleScoped IDLScopedName
+  deriving (Show)
+
+-- template_type_spec :
+--   sequence_type
+--   | string_type
+--   | fixed_pt_type
+ 
+data IDLTemplateTypeSpec =
+   IDLTmplSequence IDLSequenceType
+ | IDLTmplString IDLStringType
+ | IDLTmplFixed IDLFixedType
+  deriving (Show)
+
+-- sequence_type :
+--   SEQUENCE '<' simple_type_spec ',' positive_int_const '>'
+--   | SEQUENCE '<' simple_type_spec '>'
+
+data IDLSequenceType = IDLSequenceType IDLSimpleTypeSpec (Maybe IDLConstExp)
+  deriving (Show)
+
+-- string_type :
+--   STRING '<' positive_int_const '>'
+--   | STRING
+
+data IDLStringType = IDLStringType (Maybe IDLConstExp)
+  deriving (Show)
+
+-- fixed_pt_type :
+--   FIXED '<' positive_int_const ',' positive_int_const '>'
+
+data IDLFixedType = IDLFixedType IDLConstExp IDLConstExp
+  deriving (Show)
+
+-- struct_type :
+--   STRUCT IDENTIFIER
+--   '{' member_list '}'
+-- member_list_opt :
+--   /* empty */
+--   | member_list
+-- member_list :
+--   member
+--   | member_list member
+-- member :
+--   type_spec declarators ';'
+
+data IDLStructType =
+  IDLStructType String [IDLMember]
+  deriving (Show)
+
+data IDLMember = IDLMember IDLTypeSpec [IDLDeclarator] deriving (Show)
+
+-- const_dcl :
+--   CONST const_type IDENTIFIER '=' const_exp
+
+data IDLConstDcl = IDLConstDcl IDLConstType String IDLConstExp deriving (Show)
+
+-- const_type :
+--   integer_type
+--   | char_type
+--   | boolean_type
+--   | floating_pt_type
+--   | string_type
+--   | fixed_pt_const_type
+--   | scoped_name
+--   | octet_type
+
+data IDLConstType =
+   IDLConstTypeFloat IDLFloatingType
+ | IDLConstTypeInt IDLIntegerType
+ | IDLConstTypeString IDLStringType
+ | IDLConstTypeChar
+ | IDLConstTypeBool
+ | IDLConstTypeFixed
+ | IDLConstTypeOctet
+ | IDLConstTypeScoped IDLScopedName
+  deriving (Show)
+
+-- except_dcl :
+--   EXCEPTION IDENTIFIER
+--   '{' member_list_opt '}'
+
+data IDLExceptDcl = IDLExceptDcl String [IDLMember] deriving (Show)
+
+-- attr_dcl :
+--   readonly_attr_spec
+--   | attr_spec
+-- readonly_attr_spec :
+--   extended_attribute_opt READONLY ATTRIBUTE param_type_spec 
+--     simple_declarator get_excep_expr set_excep_expr
+-- attr_spec :
+--   extended_attribute_opt ATTRIBUTE param_type_spec 
+--     simple_declarator get_excep_expr set_excep_expr
+
+data IDLAttrDcl = IDLAttrDcl [IDLExtAttr] Bool IDLParamTypeSpec 
+  String [IDLScopedName] [IDLScopedName] deriving (Show)
+
+-- op_dcl :
+--   op_attribute_opt op_type_spec IDENTIFIER 
+--       parameter_dcls raises_expr_opt
+--   | extended_attribute_list op_attribute_opt op_type_spec IDENTIFIER
+--       parameter_dcls raises_expr_opt
+-- op_attribute_opt :
+--   /* empty */
+--   | ONEWAY
+-- op_type_spec :
+--   param_type_spec
+--   | VOID
+
+data IDLOpDcl = IDLOpDcl [IDLExtAttr] (Maybe IDLOpAttr) IDLParamTypeSpec String
+  [IDLParamDcl] [IDLScopedName] deriving (Show)
+
+data IDLOpAttr =
+  IDLOneWay
+  deriving (Show)
+
+-- parameter_dcls :
+--   '(' param_dcl_list ')'
+--   | '(' ')'
+-- param_dcl_list :
+--   param_dcl
+--   | param_dcl_list ',' param_dcl
+-- param_dcl :
+--   extended_attribute_opt param_attribute param_type_spec simple_declarator
+
+data IDLParamDcl = IDLParamDcl [IDLExtAttr] IDLParamAttr IDLParamTypeSpec String
+  deriving (Show)
+
+-- declarator :
+--   simple_declarator
+--   | complex_declarator
+
+data IDLDeclarator =
+   IDLSimpleDecl String
+ | IDLComplexDecl IDLArrayDeclarator
+  deriving (Show)
+
+-- array_declarator :
+--   IDENTIFIER fixed_array_size_list
+-- fixed_array_size_list :
+--   fixed_array_size
+--   | fixed_array_size_list fixed_array_size
+-- fixed_array_size :
+--   '[' positive_int_const ']'
+
+data IDLArrayDeclarator = IDLArrayDeclarator String [IDLConstExp] deriving (Show)
+
+-- The following combines multiple BNFs for constant expressions.
+
+data IDLConstExp =
+   IDLBinExp IDLBinaryOp IDLConstExp IDLConstExp
+ | IDLUnaryExp  IDLUnaryOp IDLConstExp
+ | IDLPrimScoped IDLScopedName
+ | IDLPrimLit IDLLiteral
+ | IDLParenExp IDLConstExp
+  deriving (Show)
+
+data IDLBinaryOp =
+   IDLOr
+ | IDLXor
+ | IDLAnd
+ | IDLShiftL
+ | IDLShiftR
+ | IDLAdd
+ | IDLSub
+ | IDLMult
+ | IDLDiv
+ | IDLRem
+  deriving (Show)
+
+data IDLUnaryOp =
+   IDLPos
+ | IDLNeg
+ | IDLNot
+  deriving (Show)
+
+data IDLLiteral =
+   IDLIntLit String
+ | IDLStringLit String
+ | IDLCharLit String
+ | IDLFixedLit String
+ | IDLFloatLit String
+ | IDLBoolLit String
+  deriving (Show)
+
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,21 @@
+module Main (main) where
+
+import Control.Monad
+import System.Process
+import System.Exit
+import Distribution.Simple
+import Distribution.Simple.Setup
+import Distribution.PackageDescription
+
+main :: IO ()
+main = defaultMainWithHooks simpleUserHooks {
+  preConf = buildLexer
+}
+
+buildLexer :: Args -> ConfigFlags -> IO HookedBuildInfo
+
+buildLexer args cflgs = do
+  let cmd = "cd cbits; make lexer-pkg"
+  runCommand cmd >>= waitForProcess
+  return emptyHookedBuildInfo
+
diff --git a/TestLex.hs b/TestLex.hs
new file mode 100644
--- /dev/null
+++ b/TestLex.hs
@@ -0,0 +1,34 @@
+------------------------------------------------------------------
+-- |
+-- Program     :  idltestlex
+-- Copyright   :  (c) Dmitry Golubovsky, 2009
+-- License     :  BSD-style
+-- 
+-- Maintainer  :  golubovsky@gmail.com
+-- Stability   :  experimental
+-- Portability :  portable
+-- 
+--
+--
+-- Test the IDL lexer
+------------------------------------------------------------------
+
+module Main where
+
+import Language.WebIDL.Lexer
+
+import Prelude hiding (putStrLn)
+import Control.Monad
+import System.Exit
+import System.IO.UTF8
+
+showToken t = "Token {tag = " ++ show (tag t) ++
+                    ",line = " ++ show (line t) ++
+                    ",column = " ++ show (column t) ++
+                    ",name = " ++ name t ++ "}"
+
+main = do
+  forever $ do z <- pickToken
+               putStrLn (showToken z)
+               when (tag z == 0) exitSuccess
+
diff --git a/cbits/Makefile b/cbits/Makefile
new file mode 100644
--- /dev/null
+++ b/cbits/Makefile
@@ -0,0 +1,44 @@
+LEX = flex
+SED = sed
+CPP = gcc -E -dD
+GHC = ghc
+HSFFIG = hsffig
+FFIPKG = ffipkg
+HSC2HS = hsc2hs -t /dev/null
+GHCLIB = `$(GHC) --print-libdir`
+
+LEX_OPT = --header-file=../include/lex.yy.h -8 --nounistd -I
+
+INCLUDE = ../include
+
+LEX_C = lex.yy.c
+LEX_H = $(INCLUDE)/lex.yy.h
+
+LEXER_H = $(INCLUDE)/lexer.h
+PARSER_H = $(INCLUDE)/parser.h
+
+LEXER_HS = lexer-tmp/HS_LEXER_H.hs
+
+all:
+	@echo "Do not run make directly: run cabal configure"
+	@exit -1
+
+# remove some c++isms
+
+$(LEX_C) $(LEX_H): lexer.ll $(LEXER_H)
+	$(LEX) $(LEX_OPT) $<
+	$(SED) -i 's/extern *\"C\"/extern /g' $(LEX_C)
+	$(SED) -i 's/for *(char\* s/char *s; for (s/g' $(LEX_C)
+	$(SED) -i 's/yyinput/input/g' $(LEX_C)
+	$(SED) -i 's/Node::getBaseObjectName()/\"Object\"/g' $(LEX_C)
+
+# Using ffipkg, build and install the LEXER package.
+
+lexer-pkg: $(LEX_C) $(LEX_H) $(LEXER_HS)
+
+$(LEXER_HS): $(LEX_C) $(LEX_H) $(LEXER_H) $(PARSER_H)
+	rm -rf lexer-tmp
+	mkdir lexer-tmp
+	cd lexer-tmp; $(FFIPKG) -I ../$(INCLUDE) -I $(GHCLIB)/include lexer.h && cabal install
+
+
diff --git a/cbits/lex.yy.c b/cbits/lex.yy.c
new file mode 100644
--- /dev/null
+++ b/cbits/lex.yy.c
@@ -0,0 +1,2640 @@
+
+#line 3 "lex.yy.c"
+
+#define  YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+#define YY_FLEX_SUBMINOR_VERSION 35
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+/* First, we deal with  platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types. 
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t; 
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+#endif /* ! C99 */
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN               (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN              (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN              (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX               (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX              (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX              (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX              (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX             (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX             (4294967295U)
+#endif
+
+#endif /* ! FLEXINT_H */
+
+#ifdef __cplusplus
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else	/* ! __cplusplus */
+
+/* C99 requires __STDC__ to be defined as 1. */
+#if defined (__STDC__)
+
+#define YY_USE_CONST
+
+#endif	/* defined (__STDC__) */
+#endif	/* ! __cplusplus */
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index.  If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition.  This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN (yy_start) = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state.  The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START (((yy_start) - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart(yyin  )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#define YY_BUF_SIZE 16384
+#endif
+
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE   ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+extern int yyleng;
+
+extern FILE *yyin, *yyout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+    #define YY_LESS_LINENO(n)
+    
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+	do \
+		{ \
+		/* Undo effects of setting up yytext. */ \
+        int yyless_macro_arg = (n); \
+        YY_LESS_LINENO(yyless_macro_arg);\
+		*yy_cp = (yy_hold_char); \
+		YY_RESTORE_YY_MORE_OFFSET \
+		(yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+		YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+		} \
+	while ( 0 )
+
+#define unput(c) yyunput( c, (yytext_ptr)  )
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+	{
+	FILE *yy_input_file;
+
+	char *yy_ch_buf;		/* input buffer */
+	char *yy_buf_pos;		/* current position in input buffer */
+
+	/* Size of input buffer in bytes, not including room for EOB
+	 * characters.
+	 */
+	yy_size_t yy_buf_size;
+
+	/* Number of characters read into yy_ch_buf, not including EOB
+	 * characters.
+	 */
+	int yy_n_chars;
+
+	/* Whether we "own" the buffer - i.e., we know we created it,
+	 * and can realloc() it to grow it, and should free() it to
+	 * delete it.
+	 */
+	int yy_is_our_buffer;
+
+	/* Whether this is an "interactive" input source; if so, and
+	 * if we're using stdio for input, then we want to use getc()
+	 * instead of fread(), to make sure we stop fetching input after
+	 * each newline.
+	 */
+	int yy_is_interactive;
+
+	/* Whether we're considered to be at the beginning of a line.
+	 * If so, '^' rules will be active on the next match, otherwise
+	 * not.
+	 */
+	int yy_at_bol;
+
+    int yy_bs_lineno; /**< The line count. */
+    int yy_bs_column; /**< The column count. */
+    
+	/* Whether to try to fill the input buffer when we reach the
+	 * end of it.
+	 */
+	int yy_fill_buffer;
+
+	int yy_buffer_status;
+
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+	/* When an EOF's been seen but there's still some text to process
+	 * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+	 * shouldn't try reading from the input source any more.  We might
+	 * still have a bunch of tokens to match, though, because of
+	 * possible backing-up.
+	 *
+	 * When we actually see the EOF, we change the status to "new"
+	 * (via yyrestart()), so that the user can continue scanning by
+	 * just pointing yyin at a new input file.
+	 */
+#define YY_BUFFER_EOF_PENDING 2
+
+	};
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* Stack of input buffers. */
+static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
+static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
+static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
+                          ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
+                          : NULL)
+
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
+
+/* yy_hold_char holds the character lost when yytext is formed. */
+static char yy_hold_char;
+static int yy_n_chars;		/* number of characters read into yy_ch_buf */
+int yyleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 0;		/* whether we need to initialize */
+static int yy_start = 0;	/* start state number */
+
+/* Flag which is used to allow yywrap()'s to do buffer switches
+ * instead of setting up a fresh yyin.  A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void yyrestart (FILE *input_file  );
+void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer  );
+YY_BUFFER_STATE yy_create_buffer (FILE *file,int size  );
+void yy_delete_buffer (YY_BUFFER_STATE b  );
+void yy_flush_buffer (YY_BUFFER_STATE b  );
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer  );
+void yypop_buffer_state (void );
+
+static void yyensure_buffer_stack (void );
+static void yy_load_buffer_state (void );
+static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file  );
+
+#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER )
+
+YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size  );
+YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str  );
+YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len  );
+
+void *yyalloc (yy_size_t  );
+void *yyrealloc (void *,yy_size_t  );
+void yyfree (void *  );
+
+#define yy_new_buffer yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+	{ \
+	if ( ! YY_CURRENT_BUFFER ){ \
+        yyensure_buffer_stack (); \
+		YY_CURRENT_BUFFER_LVALUE =    \
+            yy_create_buffer(yyin,YY_BUF_SIZE ); \
+	} \
+	YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+	}
+
+#define yy_set_bol(at_bol) \
+	{ \
+	if ( ! YY_CURRENT_BUFFER ){\
+        yyensure_buffer_stack (); \
+		YY_CURRENT_BUFFER_LVALUE =    \
+            yy_create_buffer(yyin,YY_BUF_SIZE ); \
+	} \
+	YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+	}
+
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
+/* Begin user sect3 */
+
+typedef unsigned char YY_CHAR;
+
+FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
+
+typedef int yy_state_type;
+
+extern int yylineno;
+
+int yylineno = 1;
+
+extern char *yytext;
+#define yytext_ptr yytext
+
+static yy_state_type yy_get_previous_state (void );
+static yy_state_type yy_try_NUL_trans (yy_state_type current_state  );
+static int yy_get_next_buffer (void );
+static void yy_fatal_error (yyconst char msg[]  );
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+	(yytext_ptr) = yy_bp; \
+	yyleng = (size_t) (yy_cp - yy_bp); \
+	(yy_hold_char) = *yy_cp; \
+	*yy_cp = '\0'; \
+	(yy_c_buf_p) = yy_cp;
+
+#define YY_NUM_RULES 52
+#define YY_END_OF_BUFFER 53
+/* This struct is not used in this scanner,
+   but its presence is necessary. */
+struct yy_trans_info
+	{
+	flex_int32_t yy_verify;
+	flex_int32_t yy_nxt;
+	};
+static yyconst flex_int16_t yy_accept[370] =
+    {   0,
+        0,    0,   53,   51,    1,    2,    2,   51,   40,   51,
+       51,   51,   41,   41,   51,   51,   51,   40,   40,   40,
+       40,   40,   40,   40,   40,   40,   40,   40,   40,   40,
+       40,   40,   40,   40,   40,   40,   40,   40,   51,   51,
+       51,   51,   51,   51,   51,   51,   51,   51,   51,   51,
+       51,    1,   50,   51,   51,   51,   51,    0,   46,    0,
+       40,    0,   40,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,   45,    0,   49,   45,   42,
+       47,    0,    0,   41,   37,   38,   39,   40,   40,   40,
+       40,   40,   40,   40,   40,   40,   40,   40,   40,   40,
+
+       40,   40,   40,   40,   15,   40,   40,   40,   40,   40,
+       40,   40,   40,   40,   40,   40,   40,   40,   40,   40,
+        1,   40,   40,   40,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,   50,    0,    0,
+        0,    0,    1,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,   40,   40,   40,   40,   40,    0,    0,    0,
+        0,    0,    0,    0,   44,    0,    0,    0,    0,    0,
+        0,   45,    0,    0,   45,   43,   40,   40,   40,   40,
+        3,   40,   40,   40,   40,   40,   40,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,   40,   40,   40,   40,
+
+       40,   40,   40,   40,   40,   40,   40,   24,   40,   40,
+       40,   40,   40,   40,   40,   40,   40,   40,    1,    2,
+        0,    0,    0,    0,    0,    0,    0,    0,    1,    0,
+        0,    0,   40,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,   45,   48,
+        0,   45,   40,   40,   40,   32,   40,   40,    6,   40,
+       40,   40,   40,   40,   40,   40,   40,   40,   18,   40,
+       40,   40,   40,   40,   40,   40,   40,   40,   40,   40,
+       40,   40,   40,   36,    0,    0,    0,   40,    0,   40,
+       11,   40,   40,   40,    7,   40,   40,   12,   13,   40,
+
+       16,   40,   40,   40,   22,   40,   40,   40,   40,   40,
+       29,   40,   40,   40,   40,   40,    0,    0,    0,   40,
+       21,   40,   40,    8,   40,   40,   40,   19,   20,   23,
+       25,   40,   40,   40,   30,   31,   40,   40,   40,   40,
+       40,    5,   40,   40,   40,   40,   40,   40,   33,   40,
+       40,   40,   40,   40,   40,   40,   26,   28,   40,   34,
+       40,    9,    4,   10,   14,   17,   27,   35,    0
+    } ;
+
+static yyconst flex_int32_t yy_ec[256] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
+        2,    2,    4,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    2,    1,    5,    6,    7,    1,    1,    8,    1,
+        1,    9,   10,    1,   10,   11,   12,   13,   14,   15,
+       16,   17,   17,   17,   17,   17,   18,   19,    1,   20,
+        1,   21,    1,    1,   22,   23,   23,   24,   25,   26,
+        7,    7,    7,    7,    7,   27,   28,    7,   29,    7,
+        7,   30,   31,   32,   33,    7,    7,   34,    7,    7,
+        1,   35,    1,    1,    7,    1,   36,   37,   38,   39,
+
+       40,   41,   42,   43,   44,   45,    7,   46,   47,   48,
+       49,   50,   51,   52,   53,   54,   55,   56,   57,   58,
+       59,    7,    1,    1,    1,    1,    1,   60,   61,   62,
+       62,   62,   62,   62,   62,   62,   62,   62,   63,   63,
+       63,   64,   63,   65,   65,   65,   65,   65,   65,   65,
+       65,   65,   65,   66,   67,   67,   67,   67,   68,   69,
+       70,   70,   70,   70,   70,   70,   70,   71,   72,   73,
+       70,   70,   70,   70,   74,   70,   70,   70,   70,   70,
+       73,   70,   70,   70,   70,   73,   70,   70,   70,   70,
+       70,    1,    1,   75,   76,   77,   77,   77,   77,   77,
+
+       77,   77,   77,   77,   77,   77,   77,   77,   77,   77,
+       77,   77,   77,   77,   77,   77,   77,   77,   77,   77,
+       77,   77,   77,   78,   79,   80,   81,   82,   82,   82,
+       82,   82,   82,   82,   82,   82,   83,   84,   84,   85,
+       86,   86,   86,   87,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1
+    } ;
+
+static yyconst flex_int32_t yy_meta[88] =
+    {   0,
+        1,    1,    2,    2,    1,    1,    3,    4,    1,    1,
+        1,    1,    5,    5,    5,    5,    5,    5,    1,    1,
+        1,    5,    5,    5,    5,    5,    3,    3,    3,    3,
+        3,    3,    3,    3,    3,    5,    5,    5,    5,    5,
+        5,    3,    3,    3,    3,    3,    3,    3,    3,    3,
+        3,    3,    3,    3,    3,    3,    3,    3,    3,    6,
+        6,    6,    6,    6,    6,    6,    6,    6,    6,    6,
+        6,    6,    6,    6,    3,    3,    3,    3,    1,    1,
+        1,    3,    3,    3,    3,    3,    3
+    } ;
+
+static yyconst flex_int16_t yy_base[400] =
+    {   0,
+        0,   86, 1180, 1181, 1181, 1181, 1181,   84,   55, 1144,
+       83,   82,  110,  158, 1159, 1157, 1155,  117,   80,   74,
+       75,   64,   79,  135,   87,  191,  114,   77,   81,  130,
+      141,   78,  179,  151,  181,   86,  133,  160,   78,  190,
+        0,  142,   87,   94, 1115,    0,  176,    0,  200,    0,
+      168,  216, 1181,  150,  119,  165, 1114,  240, 1181,  234,
+     1144, 1117,  264, 1098,  238,    0,  212,    0,  253,    0,
+      257,    0,  272, 1162,  329,  330, 1160, 1181,  343,  336,
+     1181,  361,    0,  375, 1181, 1181, 1181,  248,   93,  335,
+      261,  336,  309,  352,  337,  356,  343,  398,  444,  459,
+
+      148,  365,  368,  391,  379,  373,  374,  380,  381,  382,
+      383,  119,  410,  426,  389,  310,  400,  390,  401,  204,
+     1181, 1139, 1138, 1137,    0, 1105, 1100,  414, 1095, 1102,
+        0,    0,    0,    0,    0,    0,  476, 1181, 1092,  382,
+      227, 1100,  485, 1099, 1094,  474, 1089, 1096,  444,  562,
+      591,    0,  615,  630,  645, 1126, 1125,    0,    0,    0,
+        0,    0,    0,    0, 1181, 1145, 1144, 1143,  479, 1141,
+     1137,  621,  608,  485,  524,    0,  423,  452,  424,  407,
+     1119,  518,  515,  520,  521,  525,  523,    0,    0, 1083,
+        0,  584, 1078,    0, 1085,    0,  529,  542,  554,  539,
+
+      402,  552,  613,  534,  566,  627,  706, 1115,  567,  514,
+      564,  611,  612,  615,  633,  637,  614,  694, 1181, 1181,
+        0,    0,    0, 1083, 1078,  664, 1073, 1080,  666,  751,
+      780,    0,  698,    0,    0, 1057,    0,  685, 1051,    0,
+     1056,    0,    0,    0,    0,    0,    0,  765,  794, 1181,
+      809,  815,  702,  703,  820, 1081,  700,  731, 1078,  707,
+      565,  830,  823,  826,  708,  814,  815,  831, 1077,  711,
+      714,  852,  825,  822,  827,  824,  834,  828,  842,  636,
+      893,  743,  845, 1076,  873,  942,    0,  923,    0,  858,
+     1075,  851,  849,  897, 1074,  848,  860, 1073, 1072,  755,
+
+     1071,  415,  887,  888, 1070,  886,  909,  889,  915,  757,
+     1069,  771,  892,  907,  891,  984,    0,    0,    0,  890,
+     1068,  906,  921,  987,  975,  819,  913,  991,  994, 1067,
+     1066,  982,  701,  922, 1064, 1061, 1010,  989,  911,  983,
+      986, 1060,  985,  992,  998,  912,  993, 1001, 1059, 1028,
+     1006, 1008, 1018, 1016, 1039, 1019, 1057, 1046, 1055, 1056,
+     1023, 1054, 1058, 1053, 1037, 1062, 1036, 1065, 1181, 1108,
+     1112, 1117, 1043, 1040, 1011,  971,  970,  968,  967,  966,
+     1123,  938,  878,  809,  808,  737,  665,  606,  567, 1126,
+     1128, 1133,  485,  479,  391,  336,  335,  241,  108
+
+    } ;
+
+static yyconst flex_int16_t yy_def[400] =
+    {   0,
+      369,    1,  369,  369,  369,  369,  369,  370,  371,  372,
+      369,  369,  369,  369,  369,  369,  369,  371,   18,   18,
+       18,   18,   18,   18,   18,   18,   18,   18,   18,   18,
+       18,   18,   18,   18,   18,   18,   18,   18,  369,  369,
+      373,  369,  369,  369,  369,  374,  369,  375,  369,  376,
+      369,  369,  369,  369,  369,  369,  369,  370,  369,  370,
+       18,  369,   18,  369,  369,  377,  369,  378,  369,  379,
+      369,  380,  369,  369,  372,  369,  381,  369,  369,  369,
+      369,  369,  382,  369,  369,  369,  369,   18,   18,   18,
+       18,   18,   18,   18,   18,   18,   18,   18,   18,   99,
+
+       18,   18,   18,   18,   18,   18,   18,   18,   18,   18,
+       18,   18,   18,   18,   18,   18,   18,   18,   18,   18,
+      369,   18,   18,   18,  373,  369,  369,  369,  369,  369,
+      373,  373,  373,  383,  384,  385,  369,  369,  369,  369,
+      369,  369,  369,  369,  369,  369,  369,  369,  370,  370,
+      150,  386,   98,   99,   99,   18,   18,  377,  377,  377,
+      377,  387,  388,  389,  369,  369,  390,  391,  369,  392,
+      392,  369,  369,  369,  369,  393,   18,   18,   18,   18,
+       18,   18,   18,   18,   18,   18,   18,  373,  373,  373,
+      373,  369,  373,  373,  373,  373,   18,   18,   18,   18,
+
+       18,   18,   18,   18,   18,   18,   18,   18,   18,   18,
+       18,   18,   18,   18,   18,   18,   18,   18,  369,  369,
+      373,  373,  373,  369,  369,  369,  369,  369,  369,  150,
+      150,  394,   18,  377,  377,  377,  377,  369,  377,  377,
+      377,  377,  377,  377,  377,  395,  396,  369,  369,  369,
+      369,  369,   18,   18,   18,   18,   18,   18,   18,   18,
+       18,   18,   18,   18,   18,   18,   18,   18,   18,   18,
+       18,   18,   18,   18,   18,   18,   18,   18,   18,   18,
+       18,   18,   18,   18,  369,  150,  397,  262,  398,   18,
+       18,   18,   18,   18,   18,   18,   18,   18,   18,   18,
+
+       18,   18,   18,   18,   18,   18,   18,   18,   18,   18,
+       18,   18,   18,   18,   18,   18,  231,  399,  396,   18,
+       18,   18,   18,   18,   18,   18,   18,   18,   18,   18,
+       18,   18,   18,   18,   18,   18,   18,   18,   18,   18,
+       18,   18,   18,   18,   18,   18,   18,   18,   18,   18,
+       18,   18,   18,   18,   18,   18,   18,   18,   18,   18,
+       18,   18,   18,   18,   18,   18,   18,   18,    0,  369,
+      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,
+      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,
+      369,  369,  369,  369,  369,  369,  369,  369,  369
+
+    } ;
+
+static yyconst flex_int16_t yy_nxt[1269] =
+    {   0,
+        4,    5,    6,    7,    8,    4,    9,   10,    4,    4,
+       11,   12,   13,   14,   14,   14,   14,   14,   15,   16,
+       17,    9,    9,   18,    9,   19,    9,    9,   20,    9,
+        9,   21,    9,    9,    4,   22,   23,   24,   25,   26,
+       27,   28,    9,   29,    9,   30,   31,   32,   33,    9,
+        9,   34,   35,   36,   37,   38,    9,    9,    9,    4,
+        4,    4,    4,    4,    4,    4,    4,    4,    4,    4,
+        4,    4,    4,    4,   39,   40,   41,   42,   43,   44,
+       45,   46,   47,   48,   49,   50,   51,   52,   59,   62,
+       77,   53,   61,   78,   63,   76,   76,   76,   76,   76,
+
+       76,   89,   61,   61,   91,   61,   61,   61,   61,   61,
+       90,   92,   61,  108,   61,   61,  104,   93,   60,  178,
+       79,   61,   80,   80,   80,   80,   80,   94,  105,   64,
+       65,   66,   67,   81,   82,   97,   68,   69,   70,   71,
+       72,   73,   61,   83,  117,   88,  121,   61,   81,   82,
+      122,   62,  126,  128,  129,  127,   63,  102,   61,  103,
+       54,   61,  209,   61,   55,   56,   57,   83,   79,   61,
+       84,   84,   84,   84,   84,   84,   61,   95,  106,   61,
+      118,   81,   82,   96,  144,  197,  112,  145,   61,  107,
+      113,   64,   65,   66,   67,  119,   81,   82,   68,   69,
+
+       70,   71,   72,   73,   98,   99,  100,   61,  120,   61,
+      125,  125,  125,  125,  125,  125,  109,  137,  143,   61,
+      114,  138,  122,  115,  146,  147,  110,  136,  136,  136,
+      136,  136,   61,  111,  116,  132,  132,  132,  132,  132,
+      132,  132,  132,  132,   59,  319,  149,  218,  101,  123,
+      123,  123,  123,  123,  123,  123,  123,  122,  122,  122,
+      122,  122,  122,  122,  134,  134,  134,  134,  134,  134,
+      134,  134,  134,  134,   60,  177,   61,  153,  154,  155,
+      158,  158,  158,  158,  158,  158,  226,  227,  150,   61,
+      139,  151,   61,  180,  140,  141,  142,   61,   61,   61,
+
+       61,   61,   61,   61,   61,  156,  156,  156,  156,  156,
+      156,  156,  160,  160,  160,  160,  160,  160,  160,  160,
+      160,  162,  162,  162,  162,  162,  162,  162,  162,  162,
+      162,  164,  164,  164,  164,  164,   74,   61,   61,  318,
+       74,  166,   76,   76,   76,   76,   76,   76,   80,   80,
+       80,   80,   80,   81,  169,  172,  172,  172,  172,  172,
+      172,  214,  182,   61,   61,   61,   81,  173,   81,  169,
+      174,   61,  184,  175,  175,  175,  175,  175,  175,  179,
+       61,   81,  173,  167,   61,   79,  168,   84,   84,   84,
+       84,   84,   84,   61,  181,  289,   61,  186,   81,   82,
+
+      183,   61,   61,  185,  153,  154,  155,   61,   61,   61,
+       61,   61,  204,   81,   82,  187,  199,   61,   61,   61,
+      203,  207,  198,  153,  154,  155,   61,  201,   61,   61,
+       61,  256,  202,  205,  206,   61,  208,  213,   61,  153,
+      154,  155,  216,   61,  200,  210,  217,  224,   59,  215,
+      225,   61,   61,  253,   61,  327,  267,  188,  188,  188,
+      188,  188,  188,  255,  189,  189,  190,  191,  191,  191,
+      191,  191,   61,  219,  219,  219,  211,  137,   60,  212,
+       61,  138,  254,  287,  220,  220,  137,  219,  248,  176,
+      138,  249,  249,  249,  249,  249,  249,  175,  175,  175,
+
+      175,  175,  175,  192,  193,  194,  194,  194,  194,  194,
+      194,  194,  194,  194,  194,  194,  194,  194,  195,  196,
+      196,  196,  196,  196,  196,  196,  196,  196,  196,  196,
+      196,  196,  196,  229,  229,  229,  175,  175,  175,  175,
+      175,  175,   61,   61,  220,  220,   61,  229,   61,   61,
+      139,   61,  275,   61,  140,  141,  142,   61,  262,  139,
+      258,  261,   61,  140,  141,  142,   59,   61,  263,  257,
+       61,  259,  245,  260,  230,  230,  230,  230,  230,  230,
+       61,  264,   61,  230,  230,  230,  230,  230,  270,  265,
+      266,  268,   61,   61,   61,   61,   60,  230,  230,  230,
+
+      230,  230,  230,  231,  231,  231,  231,  231,  231,  271,
+      296,  244,  231,  231,  231,  231,  231,  251,  276,  274,
+      252,  252,  252,  252,  252,  252,  231,  231,  231,  231,
+      231,  231,  233,  172,  172,  172,  172,  172,  172,   61,
+       61,   61,   61,   61,   81,  173,  124,  124,  124,  124,
+      124,  124,  124,  124,  269,   61,  124,  124,  279,   81,
+      173,   61,  277,  278,   61,   61,  272,  137,  283,  280,
+      243,  138,  281,  313,  234,  234,  234,  234,  234,  234,
+      282,  235,  235,  236,  237,  237,  237,  237,  237,  238,
+      239,  240,  240,  240,  240,  240,  240,  240,  240,  240,
+
+      240,  240,  240,  240,  241,  242,  242,  242,  242,  242,
+      242,  242,  242,  242,  242,  242,  242,  242,  242,  153,
+      154,  155,   61,  285,  285,  285,   61,  291,   61,   61,
+       61,   61,  284,  288,   61,   61,   61,  285,  347,   61,
+      139,  232,   61,  293,  140,  141,  142,  157,  157,  157,
+      157,  157,  157,  157,  157,  290,  303,  157,  157,   61,
+      295,  299,  273,  286,  286,  286,  286,  286,  286,  304,
+      294,   61,  286,  286,  286,  286,  286,  249,  249,  249,
+      249,  249,  249,   61,  315,   61,  286,  286,  286,  286,
+      286,  286,  149,  149,  149,  149,  149,  149,  326,   61,
+
+      334,  149,  149,  149,  149,  149,  249,  249,  249,  249,
+      249,  249,  335,  223,  222,  149,  149,  149,  149,  149,
+      149,  252,  252,  252,  252,  252,  252,  252,  252,  252,
+      252,  252,  252,  153,  154,  155,  153,  154,  155,  153,
+      154,  155,   61,   61,  153,  154,  155,   61,   61,  300,
+       61,   61,   61,   61,   61,   61,   61,  292,   61,   61,
+      306,  307,   61,  309,  298,  153,  154,  155,  301,  310,
+       61,  344,  297,   61,  137,  308,   61,   61,  138,   61,
+       61,  311,  302,  221,  316,  322,   61,  324,   61,  312,
+      124,  124,  124,  124,  124,  124,  124,  124,  124,  124,
+
+      124,  124,  124,  124,  321,  305,  153,  154,  155,  320,
+      153,  154,  155,  325,   61,   61,   61,   61,   61,   61,
+       61,   61,  153,  154,  155,   61,  328,  329,  153,  154,
+      155,  314,  323,  340,   61,   61,  332,   61,  338,   61,
+       61,   61,  176,   61,  330,  336,  337,  139,  345,   61,
+       61,  140,  141,  142,  317,  317,  317,  317,  317,  317,
+      341,  331,  333,  317,  317,  317,  317,  317,  342,  351,
+      357,  163,  161,  159,  348,  157,  135,  317,  317,  317,
+      317,  317,  317,  157,  157,  157,  157,  157,  157,  157,
+      157,  157,  157,  157,  157,  157,  157,  153,  154,  155,
+
+      153,  154,  155,   61,  153,  154,  155,  153,  154,  155,
+       61,   61,   61,   61,   61,   61,  133,   61,  343,   61,
+       61,   61,   61,  153,  154,  155,   61,  346,  350,   61,
+      352,  355,  358,  354,   61,  356,   61,  339,   61,  353,
+      359,  153,  154,  155,   61,  131,   61,   61,  124,  362,
+      349,   61,  153,  154,  155,  361,   61,  363,  366,  153,
+      154,  155,  368,  364,   61,   61,  360,   61,  153,  154,
+      155,  153,  154,  155,   61,  153,  154,  155,  153,  154,
+      155,   61,   61,   61,   61,   61,   61,   61,   61,   61,
+       61,  365,   61,   61,   61,   61,   61,   61,   61,   61,
+
+       61,   61,   61,   61,   61,   61,   61,  367,   58,   61,
+       58,   58,   58,   58,   61,  369,   61,   74,  369,   74,
+      369,   74,   74,  170,  170,  170,  170,  170,  170,  246,
+      246,  247,  247,  170,  170,  170,  170,  170,  170,  285,
+      285,  285,  285,   61,  369,  369,  369,   61,  250,  171,
+      165,  165,  165,   61,   61,  229,  229,  229,  229,  228,
+      137,  219,  219,  219,  219,   61,   61,   61,  171,  165,
+      156,  152,   61,  148,  130,   87,   86,   85,   75,  369,
+        3,  369,  369,  369,  369,  369,  369,  369,  369,  369,
+      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,
+
+      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,
+      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,
+      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,
+      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,
+      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,
+      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,
+      369,  369,  369,  369,  369,  369,  369,  369
+    } ;
+
+static yyconst flex_int16_t yy_chk[1269] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    2,    8,    9,
+       12,    2,   22,   12,    9,   11,   11,   11,   11,   11,
+
+       11,   19,   20,   21,   21,   28,   32,   23,   19,   29,
+       20,   22,  399,   32,   36,   25,   28,   22,    8,   89,
+       13,   89,   13,   13,   13,   13,   13,   23,   29,    9,
+        9,    9,    9,   13,   13,   25,    9,    9,    9,    9,
+        9,    9,   27,   13,   36,   18,   39,  112,   13,   13,
+       39,   18,   43,   44,   44,   43,   18,   27,   30,   27,
+        2,   37,  112,   24,    2,    2,    2,   13,   14,   31,
+       14,   14,   14,   14,   14,   14,  101,   24,   30,   34,
+       37,   14,   14,   24,   55,  101,   34,   55,   38,   31,
+       34,   18,   18,   18,   18,   38,   14,   14,   18,   18,
+
+       18,   18,   18,   18,   26,   26,   26,   33,   38,   35,
+       42,   42,   42,   42,   42,   42,   33,   52,   54,   26,
+       35,   52,   54,   35,   56,   56,   33,   51,   51,   51,
+       51,   51,  120,   33,   35,   47,   47,   47,   47,   47,
+       47,   47,   47,   47,   58,  398,   60,  120,   26,   40,
+       40,   40,   40,   40,   40,   40,   40,   40,   40,   40,
+       40,   40,   40,   40,   49,   49,   49,   49,   49,   49,
+       49,   49,   49,   49,   58,   88,   88,   63,   63,   63,
+       67,   67,   67,   67,   67,   67,  141,  141,   60,   91,
+       52,   60,   63,   91,   52,   52,   52,   65,   65,   65,
+
+       65,   65,   65,   65,   65,   65,   65,   65,   65,   65,
+       65,   65,   69,   69,   69,   69,   69,   69,   69,   69,
+       69,   71,   71,   71,   71,   71,   71,   71,   71,   71,
+       71,   73,   73,   73,   73,   73,   75,   93,  116,  397,
+      396,   75,   76,   76,   76,   76,   76,   76,   80,   80,
+       80,   80,   80,   76,   76,   79,   79,   79,   79,   79,
+       79,  116,   93,   90,   92,   95,   79,   79,   76,   76,
+       82,   97,   95,   82,   82,   82,   82,   82,   82,   90,
+       94,   79,   79,   75,   96,   84,   75,   84,   84,   84,
+       84,   84,   84,  102,   92,  395,  103,   97,   84,   84,
+
+       94,  106,  107,   96,  104,  104,  104,  105,  108,  109,
+      110,  111,  107,   84,   84,   98,  103,  115,  118,  104,
+      106,  110,  102,  113,  113,  113,   98,  105,  117,  119,
+      201,  180,  105,  108,  109,  180,  111,  115,  113,  114,
+      114,  114,  118,  302,  104,  113,  119,  140,  149,  117,
+      140,  177,  179,  177,  114,  302,  201,   98,   98,   98,
+       98,   98,   98,  179,   98,   98,   98,   98,   98,   98,
+       98,   98,   99,  128,  128,  128,  114,  137,  149,  114,
+      178,  137,  178,  394,  128,  128,  143,  128,  169,  393,
+      143,  169,  169,  169,  169,  169,  169,  174,  174,  174,
+
+      174,  174,  174,   99,   99,   99,   99,   99,   99,   99,
+       99,   99,   99,   99,   99,   99,   99,   99,  100,  100,
+      100,  100,  100,  100,  100,  100,  100,  100,  100,  100,
+      100,  100,  100,  146,  146,  146,  175,  175,  175,  175,
+      175,  175,  210,  183,  146,  146,  182,  146,  184,  185,
+      137,  187,  210,  186,  137,  137,  137,  197,  187,  143,
+      183,  186,  204,  143,  143,  143,  150,  200,  197,  182,
+      198,  184,  389,  185,  150,  150,  150,  150,  150,  150,
+      202,  198,  199,  150,  150,  150,  150,  150,  204,  199,
+      200,  202,  211,  261,  205,  209,  150,  150,  150,  150,
+
+      150,  150,  150,  151,  151,  151,  151,  151,  151,  205,
+      261,  388,  151,  151,  151,  151,  151,  173,  211,  209,
+      173,  173,  173,  173,  173,  173,  151,  151,  151,  151,
+      151,  151,  153,  172,  172,  172,  172,  172,  172,  212,
+      213,  203,  217,  214,  172,  172,  192,  192,  192,  192,
+      192,  192,  192,  192,  203,  206,  192,  192,  214,  172,
+      172,  215,  212,  213,  280,  216,  206,  229,  217,  214,
+      387,  229,  215,  280,  153,  153,  153,  153,  153,  153,
+      216,  153,  153,  153,  153,  153,  153,  153,  153,  154,
+      154,  154,  154,  154,  154,  154,  154,  154,  154,  154,
+
+      154,  154,  154,  154,  155,  155,  155,  155,  155,  155,
+      155,  155,  155,  155,  155,  155,  155,  155,  155,  207,
+      207,  207,  218,  226,  226,  226,  233,  254,  257,  333,
+      253,  254,  218,  233,  207,  260,  265,  226,  333,  270,
+      229,  386,  271,  257,  229,  229,  229,  238,  238,  238,
+      238,  238,  238,  238,  238,  253,  270,  238,  238,  258,
+      260,  265,  207,  230,  230,  230,  230,  230,  230,  271,
+      258,  282,  230,  230,  230,  230,  230,  248,  248,  248,
+      248,  248,  248,  300,  282,  310,  230,  230,  230,  230,
+      230,  230,  231,  231,  231,  231,  231,  231,  300,  312,
+
+      310,  231,  231,  231,  231,  231,  249,  249,  249,  249,
+      249,  249,  312,  385,  384,  231,  231,  231,  231,  231,
+      231,  251,  251,  251,  251,  251,  251,  252,  252,  252,
+      252,  252,  252,  255,  255,  255,  263,  263,  263,  264,
+      264,  264,  266,  267,  268,  268,  268,  326,  255,  266,
+      274,  263,  276,  273,  264,  275,  278,  255,  262,  268,
+      273,  274,  277,  276,  264,  272,  272,  272,  267,  277,
+      279,  326,  263,  283,  285,  275,  296,  293,  285,  292,
+      272,  278,  268,  383,  283,  293,  290,  296,  297,  279,
+      262,  262,  262,  262,  262,  262,  262,  262,  262,  262,
+
+      262,  262,  262,  262,  292,  272,  281,  281,  281,  290,
+      294,  294,  294,  297,  306,  303,  304,  308,  320,  315,
+      313,  281,  307,  307,  307,  294,  303,  304,  309,  309,
+      309,  281,  294,  320,  322,  314,  308,  307,  315,  339,
+      346,  327,  382,  309,  306,  313,  314,  285,  327,  323,
+      334,  285,  285,  285,  286,  286,  286,  286,  286,  286,
+      322,  307,  309,  286,  286,  286,  286,  286,  323,  339,
+      346,  380,  379,  378,  334,  377,  376,  286,  286,  286,
+      286,  286,  286,  288,  288,  288,  288,  288,  288,  288,
+      288,  288,  288,  288,  288,  288,  288,  316,  316,  316,
+
+      324,  324,  324,  325,  328,  328,  328,  329,  329,  329,
+      332,  340,  316,  343,  341,  324,  375,  338,  325,  328,
+      344,  347,  329,  337,  337,  337,  345,  332,  338,  348,
+      340,  344,  347,  343,  351,  345,  352,  316,  337,  341,
+      348,  350,  350,  350,  354,  374,  353,  356,  373,  352,
+      337,  361,  355,  355,  355,  351,  350,  353,  356,  358,
+      358,  358,  361,  354,  367,  365,  350,  355,  359,  359,
+      359,  363,  363,  363,  358,  366,  366,  366,  368,  368,
+      368,  364,  362,  359,  360,  357,  363,  349,  342,  336,
+      366,  355,  335,  368,  331,  330,  321,  311,  305,  301,
+
+      299,  298,  295,  291,  284,  269,  259,  359,  370,  256,
+      370,  370,  370,  370,  371,  241,  371,  372,  239,  372,
+      236,  372,  372,  381,  381,  381,  381,  381,  381,  390,
+      390,  391,  391,  392,  392,  392,  392,  392,  392,  228,
+      227,  225,  224,  208,  195,  193,  190,  181,  171,  170,
+      168,  167,  166,  157,  156,  148,  147,  145,  144,  142,
+      139,  130,  129,  127,  126,  124,  123,  122,   77,   74,
+       64,   62,   61,   57,   45,   17,   16,   15,   10,    3,
+      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,
+      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,
+
+      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,
+      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,
+      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,
+      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,
+      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,
+      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,
+      369,  369,  369,  369,  369,  369,  369,  369
+    } ;
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+extern int yy_flex_debug;
+int yy_flex_debug = 0;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *yytext;
+#line 1 "lexer.ll"
+/*
+ * Copyright 2008, 2009 Google Inc.
+ * Copyright 2007 Nintendo Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * These coded instructions, statements, and computer programs contain
+ * software derived from the following specifications:
+ *
+ * W3C,
+ * Web IDL,
+ * W3C Working Draft 19 December 2008.
+ * http://www.w3.org/TR/WebIDL/
+ *
+ * Common Object Request Broker Architecture: Core Specification,
+ * Version 3.0.3, Object Management Group, Inc., March 2004.
+ * http://www.omg.org/technology/documents/formal/corba_iiop.htm.
+ */
+#line 33 "lexer.ll"
+
+#include "esidl.h"
+#include "parser.h"
+
+#ifndef VERBOSE
+#define PRINTF(...)     (__VA_ARGS__)
+#else
+#define PRINTF(...)     printf(__VA_ARGS__)
+#endif
+
+extern  int yyparse(void);
+
+void yyerror(const char* str);
+
+extern  int yywrap();
+
+void stepLocation()
+{
+    yylloc.first_line = yylloc.last_line;
+    yylloc.first_column = yylloc.last_column + 1;
+    yylloc.last_column += yyleng;
+}
+
+static bool poundMode = false;
+
+/* regular definitions */
+/* Lu up to \u00ff */
+/* Ll up to \u00ff */
+/* Unicode excluding USP, LS, PS, Lu and Li */
+#line 917 "lex.yy.c"
+
+#define INITIAL 0
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+static int yy_init_globals (void );
+
+/* Accessor methods to globals.
+   These are made visible to non-reentrant scanners for convenience. */
+
+int yylex_destroy (void );
+
+int yyget_debug (void );
+
+void yyset_debug (int debug_flag  );
+
+YY_EXTRA_TYPE yyget_extra (void );
+
+void yyset_extra (YY_EXTRA_TYPE user_defined  );
+
+FILE *yyget_in (void );
+
+void yyset_in  (FILE * in_str  );
+
+FILE *yyget_out (void );
+
+void yyset_out  (FILE * out_str  );
+
+int yyget_leng (void );
+
+char *yyget_text (void );
+
+int yyget_lineno (void );
+
+void yyset_lineno (int line_number  );
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern  int yywrap (void );
+#else
+extern int yywrap (void );
+#endif
+#endif
+
+    static void yyunput (int c,char *buf_ptr  );
+    
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char *,yyconst char *,int );
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * );
+#endif
+
+#ifndef YY_NO_INPUT
+
+#ifdef __cplusplus
+static int input (void );
+#else
+static int input (void );
+#endif
+
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO fwrite( yytext, yyleng, 1, yyout )
+#endif
+
+/* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+	if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
+		{ \
+		int c = '*'; \
+		int n; \
+		for ( n = 0; n < max_size && \
+			     (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+			buf[n] = (char) c; \
+		if ( c == '\n' ) \
+			buf[n++] = (char) c; \
+		if ( c == EOF && ferror( yyin ) ) \
+			YY_FATAL_ERROR( "input in flex scanner failed" ); \
+		result = n; \
+		} \
+	else \
+		{ \
+		errno=0; \
+		while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
+			{ \
+			if( errno != EINTR) \
+				{ \
+				YY_FATAL_ERROR( "input in flex scanner failed" ); \
+				break; \
+				} \
+			errno=0; \
+			clearerr(yyin); \
+			} \
+		}\
+\
+
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* end tables serialization structures and prototypes */
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+
+extern int yylex (void);
+
+#define YY_DECL int yylex (void)
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+	if ( yyleng > 0 ) \
+		YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \
+				(yytext[yyleng - 1] == '\n'); \
+	YY_USER_ACTION
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+	register yy_state_type yy_current_state;
+	register char *yy_cp, *yy_bp;
+	register int yy_act;
+    
+#line 103 "lexer.ll"
+
+
+#line 1097 "lex.yy.c"
+
+	if ( !(yy_init) )
+		{
+		(yy_init) = 1;
+
+#ifdef YY_USER_INIT
+		YY_USER_INIT;
+#endif
+
+		if ( ! (yy_start) )
+			(yy_start) = 1;	/* first start state */
+
+		if ( ! yyin )
+			yyin = stdin;
+
+		if ( ! yyout )
+			yyout = stdout;
+
+		if ( ! YY_CURRENT_BUFFER ) {
+			yyensure_buffer_stack ();
+			YY_CURRENT_BUFFER_LVALUE =
+				yy_create_buffer(yyin,YY_BUF_SIZE );
+		}
+
+		yy_load_buffer_state( );
+		}
+
+	while ( 1 )		/* loops until end-of-file is reached */
+		{
+		yy_cp = (yy_c_buf_p);
+
+		/* Support of yytext. */
+		*yy_cp = (yy_hold_char);
+
+		/* yy_bp points to the position in yy_ch_buf of the start of
+		 * the current run.
+		 */
+		yy_bp = yy_cp;
+
+		yy_current_state = (yy_start);
+		yy_current_state += YY_AT_BOL();
+yy_match:
+		do
+			{
+			register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+			if ( yy_accept[yy_current_state] )
+				{
+				(yy_last_accepting_state) = yy_current_state;
+				(yy_last_accepting_cpos) = yy_cp;
+				}
+			while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+				{
+				yy_current_state = (int) yy_def[yy_current_state];
+				if ( yy_current_state >= 370 )
+					yy_c = yy_meta[(unsigned int) yy_c];
+				}
+			yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+			++yy_cp;
+			}
+		while ( yy_base[yy_current_state] != 1181 );
+
+yy_find_action:
+		yy_act = yy_accept[yy_current_state];
+		if ( yy_act == 0 )
+			{ /* have to back up */
+			yy_cp = (yy_last_accepting_cpos);
+			yy_current_state = (yy_last_accepting_state);
+			yy_act = yy_accept[yy_current_state];
+			}
+
+		YY_DO_BEFORE_ACTION;
+
+do_action:	/* This label is used only to access EOF actions. */
+
+		switch ( yy_act )
+	{ /* beginning of action switch */
+			case 0: /* must back up */
+			/* undo the effects of YY_DO_BEFORE_ACTION */
+			*yy_cp = (yy_hold_char);
+			yy_cp = (yy_last_accepting_cpos);
+			yy_current_state = (yy_last_accepting_state);
+			goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 105 "lexer.ll"
+{
+                        ++yylloc.last_column;
+                    }
+	YY_BREAK
+case 2:
+/* rule 2 can match eol */
+YY_RULE_SETUP
+#line 108 "lexer.ll"
+{
+                        if (*yytext == '\n')
+                        {
+                            ++yylloc.last_line;
+                            yylloc.last_column = 0;
+                            if (poundMode)
+                            {
+                                poundMode = false;
+                                return EOL;
+                            }
+                        }
+                    }
+	YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 121 "lexer.ll"
+{
+                        stepLocation();
+                        return ANY;
+                    }
+	YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 125 "lexer.ll"
+{
+                        stepLocation();
+                        return ATTRIBUTE;
+                    }
+	YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 129 "lexer.ll"
+{
+                        stepLocation();
+                        return BOOLEAN;
+                    }
+	YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 133 "lexer.ll"
+{
+                        stepLocation();
+                        return CHAR;
+                    }
+	YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 137 "lexer.ll"
+{
+                        stepLocation();
+                        return CONST;
+                    }
+	YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 141 "lexer.ll"
+{
+                        stepLocation();
+                        return DOUBLE;
+                    }
+	YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 145 "lexer.ll"
+{
+                        stepLocation();
+                        return STRING;
+                    }
+	YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 149 "lexer.ll"
+{
+                        stepLocation();
+                        return EXCEPTION;
+                    }
+	YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 153 "lexer.ll"
+{
+                        stepLocation();
+                        return FALSE;
+                    }
+	YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 157 "lexer.ll"
+{
+                        stepLocation();
+                        return FIXED;
+                    }
+	YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 161 "lexer.ll"
+{
+                        stepLocation();
+                        return FLOAT;
+                    }
+	YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 165 "lexer.ll"
+{
+                        stepLocation();
+                        return GETRAISES;
+                    }
+	YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 169 "lexer.ll"
+{
+                        stepLocation();
+                        return IN;
+                    }
+	YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 173 "lexer.ll"
+{
+                        stepLocation();
+                        return INOUT;
+                    }
+	YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 177 "lexer.ll"
+{
+                        stepLocation();
+                        return INTERFACE;
+                    }
+	YY_BREAK
+case 18:
+YY_RULE_SETUP
+#line 181 "lexer.ll"
+{
+                        stepLocation();
+                        return LONG;
+                    }
+	YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 185 "lexer.ll"
+{
+                        stepLocation();
+                        return MODULE;
+                    }
+	YY_BREAK
+case 20:
+YY_RULE_SETUP
+#line 189 "lexer.ll"
+{
+                        stepLocation();
+                        return NATIVE;
+                    }
+	YY_BREAK
+case 21:
+YY_RULE_SETUP
+#line 193 "lexer.ll"
+{
+                        stepLocation();
+                        yylval.name = strdup("Object");
+                        return IDENTIFIER;
+                    }
+	YY_BREAK
+case 22:
+YY_RULE_SETUP
+#line 198 "lexer.ll"
+{
+                        stepLocation();
+                        return OCTET;
+                    }
+	YY_BREAK
+case 23:
+YY_RULE_SETUP
+#line 202 "lexer.ll"
+{
+                        stepLocation();
+                        return ONEWAY;
+                    }
+	YY_BREAK
+case 24:
+YY_RULE_SETUP
+#line 206 "lexer.ll"
+{
+                        stepLocation();
+                        return OUT;
+                    }
+	YY_BREAK
+case 25:
+YY_RULE_SETUP
+#line 210 "lexer.ll"
+{
+                        stepLocation();
+                        return RAISES;
+                    }
+	YY_BREAK
+case 26:
+YY_RULE_SETUP
+#line 214 "lexer.ll"
+{
+                        stepLocation();
+                        return READONLY;
+                    }
+	YY_BREAK
+case 27:
+YY_RULE_SETUP
+#line 218 "lexer.ll"
+{
+                        stepLocation();
+                        return SETRAISES;
+                    }
+	YY_BREAK
+case 28:
+YY_RULE_SETUP
+#line 222 "lexer.ll"
+{
+                        stepLocation();
+                        return SEQUENCE;
+                    }
+	YY_BREAK
+case 29:
+YY_RULE_SETUP
+#line 226 "lexer.ll"
+{
+                        stepLocation();
+                        return SHORT;
+                    }
+	YY_BREAK
+case 30:
+YY_RULE_SETUP
+#line 230 "lexer.ll"
+{
+                        stepLocation();
+                        return STRING;
+                    }
+	YY_BREAK
+case 31:
+YY_RULE_SETUP
+#line 234 "lexer.ll"
+{
+                        stepLocation();
+                        return STRUCT;
+                    }
+	YY_BREAK
+case 32:
+YY_RULE_SETUP
+#line 238 "lexer.ll"
+{
+                        stepLocation();
+                        return TRUE;
+                    }
+	YY_BREAK
+case 33:
+YY_RULE_SETUP
+#line 242 "lexer.ll"
+{
+                        stepLocation();
+                        return TYPEDEF;
+                    }
+	YY_BREAK
+case 34:
+YY_RULE_SETUP
+#line 246 "lexer.ll"
+{
+                        stepLocation();
+                        return UNSIGNED;
+                    }
+	YY_BREAK
+case 35:
+YY_RULE_SETUP
+#line 250 "lexer.ll"
+{
+                        stepLocation();
+                        return VALUETYPE;
+                    }
+	YY_BREAK
+case 36:
+YY_RULE_SETUP
+#line 254 "lexer.ll"
+{
+                        stepLocation();
+                        return VOID;
+                    }
+	YY_BREAK
+case 37:
+YY_RULE_SETUP
+#line 259 "lexer.ll"
+{
+                        stepLocation();
+                        return OP_SCOPE;
+                    }
+	YY_BREAK
+case 38:
+YY_RULE_SETUP
+#line 263 "lexer.ll"
+{
+                        stepLocation();
+                        return OP_SHL;
+                    }
+	YY_BREAK
+case 39:
+YY_RULE_SETUP
+#line 267 "lexer.ll"
+{
+                        stepLocation();
+                        return OP_SHR;
+                    }
+	YY_BREAK
+case 40:
+YY_RULE_SETUP
+#line 272 "lexer.ll"
+{
+                        stepLocation();
+                        yylval.name = strdup(yytext);
+                        return IDENTIFIER;
+                    }
+	YY_BREAK
+case 41:
+YY_RULE_SETUP
+#line 278 "lexer.ll"
+{
+                        stepLocation();
+                        yylval.name = strdup(yytext);
+                        return INTEGER_LITERAL;
+                    }
+	YY_BREAK
+case 42:
+YY_RULE_SETUP
+#line 284 "lexer.ll"
+{
+                        stepLocation();
+                        yylval.name = strdup(yytext);
+                        return INTEGER_LITERAL;
+                    }
+	YY_BREAK
+case 43:
+YY_RULE_SETUP
+#line 290 "lexer.ll"
+{
+                        stepLocation();
+                        yylval.name = strdup(yytext);
+                        return INTEGER_LITERAL;
+                    }
+	YY_BREAK
+case 44:
+YY_RULE_SETUP
+#line 296 "lexer.ll"
+{
+                        stepLocation();
+                        yylval.name = strdup(yytext);
+                        return CHARACTER_LITERAL;
+                    }
+	YY_BREAK
+case 45:
+YY_RULE_SETUP
+#line 302 "lexer.ll"
+{
+                        stepLocation();
+                        yylval.name = strdup(yytext);
+                        return FLOATING_PT_LITERAL;
+                    }
+	YY_BREAK
+case 46:
+YY_RULE_SETUP
+#line 308 "lexer.ll"
+{
+                        stepLocation();
+                        yylval.name = strdup(yytext);
+                        return STRING_LITERAL;
+                    }
+	YY_BREAK
+case 47:
+YY_RULE_SETUP
+#line 314 "lexer.ll"
+{
+                        stepLocation();
+                        yylval.name = strdup(yytext);
+                        return FIXED_PT_LITERAL;
+                    }
+	YY_BREAK
+case 48:
+/* rule 48 can match eol */
+YY_RULE_SETUP
+#line 320 "lexer.ll"
+{
+                        /* MultiLineComment */
+                        char *s; for (s = yytext; *s; ++s)
+                        {
+                            if (*s == '\n')
+                            {
+                                ++yylloc.last_line;
+                                yylloc.last_column = 0;
+                            }
+                            else
+                            {
+                                ++yylloc.last_column;
+                            }
+                        }
+                        if (strncmp(yytext, "/**", 3) == 0)
+                        {
+                            /* Javadoc style comment */
+                            yylval.name = strdup(yytext);
+                            return JAVADOC;
+                        }
+                    }
+	YY_BREAK
+case 49:
+YY_RULE_SETUP
+#line 342 "lexer.ll"
+{
+                        /* SingleLineComment */
+                        int c;
+
+                        do
+                        {
+                            c = input();
+                        } while (c != '\n' && c != '\r' && c != EOF);
+                        ++yylloc.last_line;
+                        yylloc.last_column = 0;
+                    }
+	YY_BREAK
+case 50:
+YY_RULE_SETUP
+#line 354 "lexer.ll"
+{
+                        stepLocation();
+                        poundMode = true;
+                        return POUND_SIGN;
+                    }
+	YY_BREAK
+case 51:
+YY_RULE_SETUP
+#line 360 "lexer.ll"
+{
+                        stepLocation();
+                        return (int) yytext[0];
+                    }
+	YY_BREAK
+case 52:
+YY_RULE_SETUP
+#line 365 "lexer.ll"
+ECHO;
+	YY_BREAK
+#line 1637 "lex.yy.c"
+case YY_STATE_EOF(INITIAL):
+	yyterminate();
+
+	case YY_END_OF_BUFFER:
+		{
+		/* Amount of text matched not including the EOB char. */
+		int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
+
+		/* Undo the effects of YY_DO_BEFORE_ACTION. */
+		*yy_cp = (yy_hold_char);
+		YY_RESTORE_YY_MORE_OFFSET
+
+		if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+			{
+			/* We're scanning a new file or input source.  It's
+			 * possible that this happened because the user
+			 * just pointed yyin at a new source and called
+			 * yylex().  If so, then we have to assure
+			 * consistency between YY_CURRENT_BUFFER and our
+			 * globals.  Here is the right place to do so, because
+			 * this is the first action (other than possibly a
+			 * back-up) that will match for the new input source.
+			 */
+			(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+			YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
+			YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+			}
+
+		/* Note that here we test for yy_c_buf_p "<=" to the position
+		 * of the first EOB in the buffer, since yy_c_buf_p will
+		 * already have been incremented past the NUL character
+		 * (since all states make transitions on EOB to the
+		 * end-of-buffer state).  Contrast this with the test
+		 * in input().
+		 */
+		if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+			{ /* This was really a NUL. */
+			yy_state_type yy_next_state;
+
+			(yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
+
+			yy_current_state = yy_get_previous_state(  );
+
+			/* Okay, we're now positioned to make the NUL
+			 * transition.  We couldn't have
+			 * yy_get_previous_state() go ahead and do it
+			 * for us because it doesn't know how to deal
+			 * with the possibility of jamming (and we don't
+			 * want to build jamming into it because then it
+			 * will run more slowly).
+			 */
+
+			yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+			yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+
+			if ( yy_next_state )
+				{
+				/* Consume the NUL. */
+				yy_cp = ++(yy_c_buf_p);
+				yy_current_state = yy_next_state;
+				goto yy_match;
+				}
+
+			else
+				{
+				yy_cp = (yy_c_buf_p);
+				goto yy_find_action;
+				}
+			}
+
+		else switch ( yy_get_next_buffer(  ) )
+			{
+			case EOB_ACT_END_OF_FILE:
+				{
+				(yy_did_buffer_switch_on_eof) = 0;
+
+				if ( yywrap( ) )
+					{
+					/* Note: because we've taken care in
+					 * yy_get_next_buffer() to have set up
+					 * yytext, we can now set up
+					 * yy_c_buf_p so that if some total
+					 * hoser (like flex itself) wants to
+					 * call the scanner after we return the
+					 * YY_NULL, it'll still work - another
+					 * YY_NULL will get returned.
+					 */
+					(yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
+
+					yy_act = YY_STATE_EOF(YY_START);
+					goto do_action;
+					}
+
+				else
+					{
+					if ( ! (yy_did_buffer_switch_on_eof) )
+						YY_NEW_FILE;
+					}
+				break;
+				}
+
+			case EOB_ACT_CONTINUE_SCAN:
+				(yy_c_buf_p) =
+					(yytext_ptr) + yy_amount_of_matched_text;
+
+				yy_current_state = yy_get_previous_state(  );
+
+				yy_cp = (yy_c_buf_p);
+				yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+				goto yy_match;
+
+			case EOB_ACT_LAST_MATCH:
+				(yy_c_buf_p) =
+				&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
+
+				yy_current_state = yy_get_previous_state(  );
+
+				yy_cp = (yy_c_buf_p);
+				yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+				goto yy_find_action;
+			}
+		break;
+		}
+
+	default:
+		YY_FATAL_ERROR(
+			"fatal flex scanner internal error--no action found" );
+	} /* end of action switch */
+		} /* end of scanning one token */
+} /* end of yylex */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ *	EOB_ACT_LAST_MATCH -
+ *	EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ *	EOB_ACT_END_OF_FILE - end of file
+ */
+static int yy_get_next_buffer (void)
+{
+    	register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+	register char *source = (yytext_ptr);
+	register int number_to_move, i;
+	int ret_val;
+
+	if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
+		YY_FATAL_ERROR(
+		"fatal flex scanner internal error--end of buffer missed" );
+
+	if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+		{ /* Don't try to fill the buffer, so this is an EOF. */
+		if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
+			{
+			/* We matched a single character, the EOB, so
+			 * treat this as a final EOF.
+			 */
+			return EOB_ACT_END_OF_FILE;
+			}
+
+		else
+			{
+			/* We matched some text prior to the EOB, first
+			 * process it.
+			 */
+			return EOB_ACT_LAST_MATCH;
+			}
+		}
+
+	/* Try to read more data. */
+
+	/* First move last chars to start of buffer. */
+	number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1;
+
+	for ( i = 0; i < number_to_move; ++i )
+		*(dest++) = *(source++);
+
+	if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+		/* don't do the read, it's not guaranteed to return an EOF,
+		 * just force an EOF
+		 */
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
+
+	else
+		{
+			int num_to_read =
+			YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+		while ( num_to_read <= 0 )
+			{ /* Not enough room in the buffer - grow it. */
+
+			/* just a shorter name for the current buffer */
+			YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
+
+			int yy_c_buf_p_offset =
+				(int) ((yy_c_buf_p) - b->yy_ch_buf);
+
+			if ( b->yy_is_our_buffer )
+				{
+				int new_size = b->yy_buf_size * 2;
+
+				if ( new_size <= 0 )
+					b->yy_buf_size += b->yy_buf_size / 8;
+				else
+					b->yy_buf_size *= 2;
+
+				b->yy_ch_buf = (char *)
+					/* Include room in for 2 EOB chars. */
+					yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2  );
+				}
+			else
+				/* Can't grow it, we don't own it. */
+				b->yy_ch_buf = 0;
+
+			if ( ! b->yy_ch_buf )
+				YY_FATAL_ERROR(
+				"fatal error - scanner input buffer overflow" );
+
+			(yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+			num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+						number_to_move - 1;
+
+			}
+
+		if ( num_to_read > YY_READ_BUF_SIZE )
+			num_to_read = YY_READ_BUF_SIZE;
+
+		/* Read in more data. */
+		YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+			(yy_n_chars), (size_t) num_to_read );
+
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+		}
+
+	if ( (yy_n_chars) == 0 )
+		{
+		if ( number_to_move == YY_MORE_ADJ )
+			{
+			ret_val = EOB_ACT_END_OF_FILE;
+			yyrestart(yyin  );
+			}
+
+		else
+			{
+			ret_val = EOB_ACT_LAST_MATCH;
+			YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+				YY_BUFFER_EOF_PENDING;
+			}
+		}
+
+	else
+		ret_val = EOB_ACT_CONTINUE_SCAN;
+
+	if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+		/* Extend the array by 50%, plus the number we really need. */
+		yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
+		YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size  );
+		if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+			YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+	}
+
+	(yy_n_chars) += number_to_move;
+	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
+	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
+
+	(yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+	return ret_val;
+}
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+    static yy_state_type yy_get_previous_state (void)
+{
+	register yy_state_type yy_current_state;
+	register char *yy_cp;
+    
+	yy_current_state = (yy_start);
+	yy_current_state += YY_AT_BOL();
+
+	for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
+		{
+		register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+		if ( yy_accept[yy_current_state] )
+			{
+			(yy_last_accepting_state) = yy_current_state;
+			(yy_last_accepting_cpos) = yy_cp;
+			}
+		while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+			{
+			yy_current_state = (int) yy_def[yy_current_state];
+			if ( yy_current_state >= 370 )
+				yy_c = yy_meta[(unsigned int) yy_c];
+			}
+		yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+		}
+
+	return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ *	next_state = yy_try_NUL_trans( current_state );
+ */
+    static yy_state_type yy_try_NUL_trans  (yy_state_type yy_current_state )
+{
+	register int yy_is_jam;
+    	register char *yy_cp = (yy_c_buf_p);
+
+	register YY_CHAR yy_c = 1;
+	if ( yy_accept[yy_current_state] )
+		{
+		(yy_last_accepting_state) = yy_current_state;
+		(yy_last_accepting_cpos) = yy_cp;
+		}
+	while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+		{
+		yy_current_state = (int) yy_def[yy_current_state];
+		if ( yy_current_state >= 370 )
+			yy_c = yy_meta[(unsigned int) yy_c];
+		}
+	yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+	yy_is_jam = (yy_current_state == 369);
+
+	return yy_is_jam ? 0 : yy_current_state;
+}
+
+    static void yyunput (int c, register char * yy_bp )
+{
+	register char *yy_cp;
+    
+    yy_cp = (yy_c_buf_p);
+
+	/* undo effects of setting up yytext */
+	*yy_cp = (yy_hold_char);
+
+	if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+		{ /* need to shift things up to make room */
+		/* +2 for EOB chars. */
+		register int number_to_move = (yy_n_chars) + 2;
+		register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
+					YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
+		register char *source =
+				&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
+
+		while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+			*--dest = *--source;
+
+		yy_cp += (int) (dest - source);
+		yy_bp += (int) (dest - source);
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
+			(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
+
+		if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+			YY_FATAL_ERROR( "flex scanner push-back overflow" );
+		}
+
+	*--yy_cp = (char) c;
+
+	(yytext_ptr) = yy_bp;
+	(yy_hold_char) = *yy_cp;
+	(yy_c_buf_p) = yy_cp;
+}
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+    static int input (void)
+#else
+    static int input  (void)
+#endif
+
+{
+	int c;
+    
+	*(yy_c_buf_p) = (yy_hold_char);
+
+	if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
+		{
+		/* yy_c_buf_p now points to the character we want to return.
+		 * If this occurs *before* the EOB characters, then it's a
+		 * valid NUL; if not, then we've hit the end of the buffer.
+		 */
+		if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+			/* This was really a NUL. */
+			*(yy_c_buf_p) = '\0';
+
+		else
+			{ /* need more input */
+			int offset = (yy_c_buf_p) - (yytext_ptr);
+			++(yy_c_buf_p);
+
+			switch ( yy_get_next_buffer(  ) )
+				{
+				case EOB_ACT_LAST_MATCH:
+					/* This happens because yy_g_n_b()
+					 * sees that we've accumulated a
+					 * token and flags that we need to
+					 * try matching the token before
+					 * proceeding.  But for input(),
+					 * there's no matching to consider.
+					 * So convert the EOB_ACT_LAST_MATCH
+					 * to EOB_ACT_END_OF_FILE.
+					 */
+
+					/* Reset buffer status. */
+					yyrestart(yyin );
+
+					/*FALLTHROUGH*/
+
+				case EOB_ACT_END_OF_FILE:
+					{
+					if ( yywrap( ) )
+						return EOF;
+
+					if ( ! (yy_did_buffer_switch_on_eof) )
+						YY_NEW_FILE;
+#ifdef __cplusplus
+					return input();
+#else
+					return input();
+#endif
+					}
+
+				case EOB_ACT_CONTINUE_SCAN:
+					(yy_c_buf_p) = (yytext_ptr) + offset;
+					break;
+				}
+			}
+		}
+
+	c = *(unsigned char *) (yy_c_buf_p);	/* cast for 8-bit char's */
+	*(yy_c_buf_p) = '\0';	/* preserve yytext */
+	(yy_hold_char) = *++(yy_c_buf_p);
+
+	YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n');
+
+	return c;
+}
+#endif	/* ifndef YY_NO_INPUT */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ * 
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+    void yyrestart  (FILE * input_file )
+{
+    
+	if ( ! YY_CURRENT_BUFFER ){
+        yyensure_buffer_stack ();
+		YY_CURRENT_BUFFER_LVALUE =
+            yy_create_buffer(yyin,YY_BUF_SIZE );
+	}
+
+	yy_init_buffer(YY_CURRENT_BUFFER,input_file );
+	yy_load_buffer_state( );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ * 
+ */
+    void yy_switch_to_buffer  (YY_BUFFER_STATE  new_buffer )
+{
+    
+	/* TODO. We should be able to replace this entire function body
+	 * with
+	 *		yypop_buffer_state();
+	 *		yypush_buffer_state(new_buffer);
+     */
+	yyensure_buffer_stack ();
+	if ( YY_CURRENT_BUFFER == new_buffer )
+		return;
+
+	if ( YY_CURRENT_BUFFER )
+		{
+		/* Flush out information for old buffer. */
+		*(yy_c_buf_p) = (yy_hold_char);
+		YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+		}
+
+	YY_CURRENT_BUFFER_LVALUE = new_buffer;
+	yy_load_buffer_state( );
+
+	/* We don't actually know whether we did this switch during
+	 * EOF (yywrap()) processing, but the only time this flag
+	 * is looked at is after yywrap() is called, so it's safe
+	 * to go ahead and always set it.
+	 */
+	(yy_did_buffer_switch_on_eof) = 1;
+}
+
+static void yy_load_buffer_state  (void)
+{
+    	(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+	(yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+	yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+	(yy_hold_char) = *(yy_c_buf_p);
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ * 
+ * @return the allocated buffer state.
+ */
+    YY_BUFFER_STATE yy_create_buffer  (FILE * file, int  size )
+{
+	YY_BUFFER_STATE b;
+    
+	b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state )  );
+	if ( ! b )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+	b->yy_buf_size = size;
+
+	/* yy_ch_buf has to be 2 characters longer than the size given because
+	 * we need to put in 2 end-of-buffer characters.
+	 */
+	b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2  );
+	if ( ! b->yy_ch_buf )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+	b->yy_is_our_buffer = 1;
+
+	yy_init_buffer(b,file );
+
+	return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with yy_create_buffer()
+ * 
+ */
+    void yy_delete_buffer (YY_BUFFER_STATE  b )
+{
+    
+	if ( ! b )
+		return;
+
+	if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+		YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+
+	if ( b->yy_is_our_buffer )
+		yyfree((void *) b->yy_ch_buf  );
+
+	yyfree((void *) b  );
+}
+
+#ifndef __cplusplus
+extern int isatty (int );
+#endif /* __cplusplus */
+    
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a yyrestart() or at EOF.
+ */
+    static void yy_init_buffer  (YY_BUFFER_STATE  b, FILE * file )
+
+{
+	int oerrno = errno;
+    
+	yy_flush_buffer(b );
+
+	b->yy_input_file = file;
+	b->yy_fill_buffer = 1;
+
+    /* If b is the current buffer, then yy_init_buffer was _probably_
+     * called from yyrestart() or through yy_get_next_buffer.
+     * In that case, we don't want to reset the lineno or column.
+     */
+    if (b != YY_CURRENT_BUFFER){
+        b->yy_bs_lineno = 1;
+        b->yy_bs_column = 0;
+    }
+
+        b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+    
+	errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ * 
+ */
+    void yy_flush_buffer (YY_BUFFER_STATE  b )
+{
+    	if ( ! b )
+		return;
+
+	b->yy_n_chars = 0;
+
+	/* We always need two end-of-buffer characters.  The first causes
+	 * a transition to the end-of-buffer state.  The second causes
+	 * a jam in that state.
+	 */
+	b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+	b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+	b->yy_buf_pos = &b->yy_ch_buf[0];
+
+	b->yy_at_bol = 1;
+	b->yy_buffer_status = YY_BUFFER_NEW;
+
+	if ( b == YY_CURRENT_BUFFER )
+		yy_load_buffer_state( );
+}
+
+/** Pushes the new state onto the stack. The new state becomes
+ *  the current state. This function will allocate the stack
+ *  if necessary.
+ *  @param new_buffer The new state.
+ *  
+ */
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer )
+{
+    	if (new_buffer == NULL)
+		return;
+
+	yyensure_buffer_stack();
+
+	/* This block is copied from yy_switch_to_buffer. */
+	if ( YY_CURRENT_BUFFER )
+		{
+		/* Flush out information for old buffer. */
+		*(yy_c_buf_p) = (yy_hold_char);
+		YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+		}
+
+	/* Only push if top exists. Otherwise, replace top. */
+	if (YY_CURRENT_BUFFER)
+		(yy_buffer_stack_top)++;
+	YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+	/* copied from yy_switch_to_buffer. */
+	yy_load_buffer_state( );
+	(yy_did_buffer_switch_on_eof) = 1;
+}
+
+/** Removes and deletes the top of the stack, if present.
+ *  The next element becomes the new top.
+ *  
+ */
+void yypop_buffer_state (void)
+{
+    	if (!YY_CURRENT_BUFFER)
+		return;
+
+	yy_delete_buffer(YY_CURRENT_BUFFER );
+	YY_CURRENT_BUFFER_LVALUE = NULL;
+	if ((yy_buffer_stack_top) > 0)
+		--(yy_buffer_stack_top);
+
+	if (YY_CURRENT_BUFFER) {
+		yy_load_buffer_state( );
+		(yy_did_buffer_switch_on_eof) = 1;
+	}
+}
+
+/* Allocates the stack if it does not exist.
+ *  Guarantees space for at least one push.
+ */
+static void yyensure_buffer_stack (void)
+{
+	int num_to_alloc;
+    
+	if (!(yy_buffer_stack)) {
+
+		/* First allocation is just for 2 elements, since we don't know if this
+		 * scanner will even need a stack. We use 2 instead of 1 to avoid an
+		 * immediate realloc on the next call.
+         */
+		num_to_alloc = 1;
+		(yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
+								(num_to_alloc * sizeof(struct yy_buffer_state*)
+								);
+		if ( ! (yy_buffer_stack) )
+			YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+								  
+		memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+				
+		(yy_buffer_stack_max) = num_to_alloc;
+		(yy_buffer_stack_top) = 0;
+		return;
+	}
+
+	if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
+
+		/* Increase the buffer to prepare for a possible push. */
+		int grow_size = 8 /* arbitrary grow size */;
+
+		num_to_alloc = (yy_buffer_stack_max) + grow_size;
+		(yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc
+								((yy_buffer_stack),
+								num_to_alloc * sizeof(struct yy_buffer_state*)
+								);
+		if ( ! (yy_buffer_stack) )
+			YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+
+		/* zero only the new slots.*/
+		memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
+		(yy_buffer_stack_max) = num_to_alloc;
+	}
+}
+
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ * 
+ * @return the newly allocated buffer state object. 
+ */
+YY_BUFFER_STATE yy_scan_buffer  (char * base, yy_size_t  size )
+{
+	YY_BUFFER_STATE b;
+    
+	if ( size < 2 ||
+	     base[size-2] != YY_END_OF_BUFFER_CHAR ||
+	     base[size-1] != YY_END_OF_BUFFER_CHAR )
+		/* They forgot to leave room for the EOB's. */
+		return 0;
+
+	b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state )  );
+	if ( ! b )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
+
+	b->yy_buf_size = size - 2;	/* "- 2" to take care of EOB's */
+	b->yy_buf_pos = b->yy_ch_buf = base;
+	b->yy_is_our_buffer = 0;
+	b->yy_input_file = 0;
+	b->yy_n_chars = b->yy_buf_size;
+	b->yy_is_interactive = 0;
+	b->yy_at_bol = 1;
+	b->yy_fill_buffer = 0;
+	b->yy_buffer_status = YY_BUFFER_NEW;
+
+	yy_switch_to_buffer(b  );
+
+	return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to yylex() will
+ * scan from a @e copy of @a str.
+ * @param yystr a NUL-terminated string to scan
+ * 
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ *       yy_scan_bytes() instead.
+ */
+YY_BUFFER_STATE yy_scan_string (yyconst char * yystr )
+{
+    
+	return yy_scan_bytes(yystr,strlen(yystr) );
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
+ * scan from a @e copy of @a bytes.
+ * @param bytes the byte buffer to scan
+ * @param len the number of bytes in the buffer pointed to by @a bytes.
+ * 
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_bytes  (yyconst char * yybytes, int  _yybytes_len )
+{
+	YY_BUFFER_STATE b;
+	char *buf;
+	yy_size_t n;
+	int i;
+    
+	/* Get memory for full buffer, including space for trailing EOB's. */
+	n = _yybytes_len + 2;
+	buf = (char *) yyalloc(n  );
+	if ( ! buf )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+
+	for ( i = 0; i < _yybytes_len; ++i )
+		buf[i] = yybytes[i];
+
+	buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+
+	b = yy_scan_buffer(buf,n );
+	if ( ! b )
+		YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
+
+	/* It's okay to grow etc. this buffer, and we should throw it
+	 * away when we're done.
+	 */
+	b->yy_is_our_buffer = 1;
+
+	return b;
+}
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+static void yy_fatal_error (yyconst char* msg )
+{
+    	(void) fprintf( stderr, "%s\n", msg );
+	exit( YY_EXIT_FAILURE );
+}
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+	do \
+		{ \
+		/* Undo effects of setting up yytext. */ \
+        int yyless_macro_arg = (n); \
+        YY_LESS_LINENO(yyless_macro_arg);\
+		yytext[yyleng] = (yy_hold_char); \
+		(yy_c_buf_p) = yytext + yyless_macro_arg; \
+		(yy_hold_char) = *(yy_c_buf_p); \
+		*(yy_c_buf_p) = '\0'; \
+		yyleng = yyless_macro_arg; \
+		} \
+	while ( 0 )
+
+/* Accessor  methods (get/set functions) to struct members. */
+
+/** Get the current line number.
+ * 
+ */
+int yyget_lineno  (void)
+{
+        
+    return yylineno;
+}
+
+/** Get the input stream.
+ * 
+ */
+FILE *yyget_in  (void)
+{
+        return yyin;
+}
+
+/** Get the output stream.
+ * 
+ */
+FILE *yyget_out  (void)
+{
+        return yyout;
+}
+
+/** Get the length of the current token.
+ * 
+ */
+int yyget_leng  (void)
+{
+        return yyleng;
+}
+
+/** Get the current token.
+ * 
+ */
+
+char *yyget_text  (void)
+{
+        return yytext;
+}
+
+/** Set the current line number.
+ * @param line_number
+ * 
+ */
+void yyset_lineno (int  line_number )
+{
+    
+    yylineno = line_number;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param in_str A readable stream.
+ * 
+ * @see yy_switch_to_buffer
+ */
+void yyset_in (FILE *  in_str )
+{
+        yyin = in_str ;
+}
+
+void yyset_out (FILE *  out_str )
+{
+        yyout = out_str ;
+}
+
+int yyget_debug  (void)
+{
+        return yy_flex_debug;
+}
+
+void yyset_debug (int  bdebug )
+{
+        yy_flex_debug = bdebug ;
+}
+
+static int yy_init_globals (void)
+{
+        /* Initialization is the same as for the non-reentrant scanner.
+     * This function is called from yylex_destroy(), so don't allocate here.
+     */
+
+    (yy_buffer_stack) = 0;
+    (yy_buffer_stack_top) = 0;
+    (yy_buffer_stack_max) = 0;
+    (yy_c_buf_p) = (char *) 0;
+    (yy_init) = 0;
+    (yy_start) = 0;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+    yyin = stdin;
+    yyout = stdout;
+#else
+    yyin = (FILE *) 0;
+    yyout = (FILE *) 0;
+#endif
+
+    /* For future reference: Set errno on error, since we are called by
+     * yylex_init()
+     */
+    return 0;
+}
+
+/* yylex_destroy is for both reentrant and non-reentrant scanners. */
+int yylex_destroy  (void)
+{
+    
+    /* Pop the buffer stack, destroying each element. */
+	while(YY_CURRENT_BUFFER){
+		yy_delete_buffer(YY_CURRENT_BUFFER  );
+		YY_CURRENT_BUFFER_LVALUE = NULL;
+		yypop_buffer_state();
+	}
+
+	/* Destroy the stack itself. */
+	yyfree((yy_buffer_stack) );
+	(yy_buffer_stack) = NULL;
+
+    /* Reset the globals. This is important in a non-reentrant scanner so the next time
+     * yylex() is called, initialization will occur. */
+    yy_init_globals( );
+
+    return 0;
+}
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
+{
+	register int i;
+	for ( i = 0; i < n; ++i )
+		s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * s )
+{
+	register int n;
+	for ( n = 0; s[n]; ++n )
+		;
+
+	return n;
+}
+#endif
+
+void *yyalloc (yy_size_t  size )
+{
+	return (void *) malloc( size );
+}
+
+void *yyrealloc  (void * ptr, yy_size_t  size )
+{
+	/* The cast to (char *) in the following accommodates both
+	 * implementations that use char* generic pointers, and those
+	 * that use void* generic pointers.  It works with the latter
+	 * because both ANSI C and C++ allow castless assignment from
+	 * any pointer type to void*, and deal with argument conversions
+	 * as though doing an assignment.
+	 */
+	return (void *) realloc( (char *) ptr, size );
+}
+
+void yyfree (void * ptr )
+{
+	free( (char *) ptr );	/* see yyrealloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
+
+#line 365 "lexer.ll"
+
+
+
diff --git a/cbits/lexer.c b/cbits/lexer.c
new file mode 100644
--- /dev/null
+++ b/cbits/lexer.c
@@ -0,0 +1,16 @@
+/* C code to glue the lexer and Haskell code */
+
+#include "lexer.h"
+
+/* Globals (bad, but we are decades back now...) */
+
+YYLTYPE yylloc, *p_yylloc;
+
+tokval yylval, *p_yylval;
+
+/* Exactly as the default library libfl defines */
+
+int yywrap (void) {
+  return 1;
+}
+
diff --git a/cbits/lexer.ll b/cbits/lexer.ll
new file mode 100644
--- /dev/null
+++ b/cbits/lexer.ll
@@ -0,0 +1,365 @@
+/*
+ * Copyright 2008, 2009 Google Inc.
+ * Copyright 2007 Nintendo Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * These coded instructions, statements, and computer programs contain
+ * software derived from the following specifications:
+ *
+ * W3C,
+ * Web IDL,
+ * W3C Working Draft 19 December 2008.
+ * http://www.w3.org/TR/WebIDL/
+ *
+ * Common Object Request Broker Architecture: Core Specification,
+ * Version 3.0.3, Object Management Group, Inc., March 2004.
+ * http://www.omg.org/technology/documents/formal/corba_iiop.htm.
+ */
+
+%{
+
+#include "esidl.h"
+#include "parser.h"
+
+#ifndef VERBOSE
+#define PRINTF(...)     (__VA_ARGS__)
+#else
+#define PRINTF(...)     printf(__VA_ARGS__)
+#endif
+
+extern "C" int yyparse(void);
+
+void yyerror(const char* str);
+
+extern "C" int yywrap();
+
+void stepLocation()
+{
+    yylloc.first_line = yylloc.last_line;
+    yylloc.first_column = yylloc.last_column + 1;
+    yylloc.last_column += yyleng;
+}
+
+static bool poundMode = false;
+
+%}
+
+/* regular definitions */
+
+USP                     (\xe1\x9a\x80)|(\xe1\xa0\x8e)|(\xe2\x80[\x80-\x8a])|(\xe2\x80\xaf)|(\xe2\x81\x9f)|(\xe3\x80\x80)
+LS                      (\xe2\x80\xa8)
+PS                      (\xe2\x80\xa9)
+NBSP                    (\xc2\xa0)
+/* Lu up to \u00ff */
+Lu                      (\xc3[\x80-\x9e])
+/* Ll up to \u00ff */
+Ll                      (\xc2[\xaa\xb5\xba])|(\xc3[\x9f-\xbf])
+/* Unicode excluding USP, LS, PS, Lu and Li */
+Unicode                 ([\xc4-\xdf][\x80-\xbf])|(\xe0[\xa0-\xbf][\x80-\xbf])|(\e1[\x80-\x99][\x80-\xbf])|(\e1\9a[\x81-\xbf])|(\e1[\x9b-\x9f][\x80-\xbf])|(\e1\xa0[\x80-\x8d\x8f-\xbf])|(\e1[\xa1-\xbf][\x80-\xbf])|(\e2\x80[\x8b-\xa7\xaa-\xbf])|(\e2\x81[\x80-\x9e\xa0-\xbf])|(\e2[\x82-\xbf][\x80-\xbf])|(\e3\x80[\x81-\xbf])|(\e3[\x81-\xbf][\x80-\xbf])|([\xe4-\xec][\x80-\xbf][\x80-\xbf])|(\xed[\x80-\x9f][\x80-\xbf])|([\xee-\xef][\x80-\xbf][\x80-\xbf])|(\xf0[\x90-\xbf][\x80-\xbf][\x80-\xbf])|([\xf1-\xf3][\x80-\xbf][\x80-\xbf][\x80-\xbf])|(\xf4[\x80-\x8f][\x80-\xbf][\x80-\xbf])
+
+WhiteSpace              ([ \t\v\f]|{NBSP}|{USP})
+LineTerminator          ([\n\r]|{LS}|{PS})
+HexDigit                [0-9A-Fa-f]
+DecimalDigit            [0-9]
+HexIntegerLiteral       0(x|X){HexDigit}+
+DecimalLiteral          ({DecimalIntegerLiteral}\.[0-9]*{ExponentPart}?)|(\.[0-9]+{ExponentPart}?)|({DecimalIntegerLiteral}{ExponentPart}?)
+
+ExponentPart            (e|E)[\+\-]?[0-9]+
+DecimalIntegerLiteral   0|([1-9][0-9]*)
+OctalIntegerLiteral     (0[0-8]+)
+
+SingleEscapeCharacter   ['\"\\bfnrtv]
+NonEscapeCharacter      [^'\"\\bfnrtv\n\r]
+HexEscapeSequence       x{HexDigit}{2}
+UnicodeEscapeSequence   u{HexDigit}{4}
+CharacterEscapeSequence {SingleEscapeCharacter}|{NonEscapeCharacter}
+EscapeSequence          {CharacterEscapeSequence}|0|{HexEscapeSequence}|{UnicodeEscapeSequence}
+SingleStringCharacter   ([^'\\\n\r]|\\{EscapeSequence})
+DoubleStringCharacter   ([^\"\\\n\r]|\\{EscapeSequence})
+IdentifierStart         ([A-Za-z$_]|{Lu}|{Ll}|{Unicode})
+IdentifierPart          ([0-9]|{IdentifierStart}|(\\{UnicodeEscapeSequence}))
+Identifier              {IdentifierStart}{IdentifierPart}*
+
+FixedPointLiteral       (({DecimalIntegerLiteral}\.[0-9]*)|(\.[0-9]+)|({DecimalIntegerLiteral}))[dD]
+
+MultiLineComment        \/\*(([^*])|(\*[^/]))*\*\/
+SingleLineComment       \/\/
+
+PoundSign               ^{WhiteSpace}*#
+
+%%
+
+{WhiteSpace}        {
+                        ++yylloc.last_column;
+                    }
+{LineTerminator}    {
+                        if (*yytext == '\n')
+                        {
+                            ++yylloc.last_line;
+                            yylloc.last_column = 0;
+                            if (poundMode)
+                            {
+                                poundMode = false;
+                                return EOL;
+                            }
+                        }
+                    }
+
+any                 {
+                        stepLocation();
+                        return ANY;
+                    }
+attribute           {
+                        stepLocation();
+                        return ATTRIBUTE;
+                    }
+boolean             {
+                        stepLocation();
+                        return BOOLEAN;
+                    }
+char                {
+                        stepLocation();
+                        return CHAR;
+                    }
+const               {
+                        stepLocation();
+                        return CONST;
+                    }
+double              {
+                        stepLocation();
+                        return DOUBLE;
+                    }
+DOMString           {
+                        stepLocation();
+                        return STRING;
+                    }
+exception           {
+                        stepLocation();
+                        return EXCEPTION;
+                    }
+FALSE               {
+                        stepLocation();
+                        return FALSE;
+                    }
+fixed               {
+                        stepLocation();
+                        return FIXED;
+                    }
+float               {
+                        stepLocation();
+                        return FLOAT;
+                    }
+getraises           {
+                        stepLocation();
+                        return GETRAISES;
+                    }
+in                  {
+                        stepLocation();
+                        return IN;
+                    }
+inout               {
+                        stepLocation();
+                        return INOUT;
+                    }
+interface           {
+                        stepLocation();
+                        return INTERFACE;
+                    }
+long                {
+                        stepLocation();
+                        return LONG;
+                    }
+module              {
+                        stepLocation();
+                        return MODULE;
+                    }
+native              {
+                        stepLocation();
+                        return NATIVE;
+                    }
+Object              {
+                        stepLocation();
+                        yylval.name = strdup(Node::getBaseObjectName());
+                        return IDENTIFIER;
+                    }
+octet               {
+                        stepLocation();
+                        return OCTET;
+                    }
+oneway              {
+                        stepLocation();
+                        return ONEWAY;
+                    }
+out                 {
+                        stepLocation();
+                        return OUT;
+                    }
+raises              {
+                        stepLocation();
+                        return RAISES;
+                    }
+readonly            {
+                        stepLocation();
+                        return READONLY;
+                    }
+setraises           {
+                        stepLocation();
+                        return SETRAISES;
+                    }
+sequence            {
+                        stepLocation();
+                        return SEQUENCE;
+                    }
+short               {
+                        stepLocation();
+                        return SHORT;
+                    }
+string              {
+                        stepLocation();
+                        return STRING;
+                    }
+struct              {
+                        stepLocation();
+                        return STRUCT;
+                    }
+TRUE                {
+                        stepLocation();
+                        return TRUE;
+                    }
+typedef             {
+                        stepLocation();
+                        return TYPEDEF;
+                    }
+unsigned            {
+                        stepLocation();
+                        return UNSIGNED;
+                    }
+valuetype           {
+                        stepLocation();
+                        return VALUETYPE;
+                    }
+void                {
+                        stepLocation();
+                        return VOID;
+                    }
+
+"::"                {
+                        stepLocation();
+                        return OP_SCOPE;
+                    }
+"<<"                {
+                        stepLocation();
+                        return OP_SHL;
+                    }
+">>"                {
+                        stepLocation();
+                        return OP_SHR;
+                    }
+
+{Identifier}        {
+                        stepLocation();
+                        yylval.name = strdup(yytext);
+                        return IDENTIFIER;
+                    }
+
+{DecimalIntegerLiteral} {
+                        stepLocation();
+                        yylval.name = strdup(yytext);
+                        return INTEGER_LITERAL;
+                    }
+
+{OctalIntegerLiteral}   {
+                        stepLocation();
+                        yylval.name = strdup(yytext);
+                        return INTEGER_LITERAL;
+                    }
+
+{HexIntegerLiteral} {
+                        stepLocation();
+                        yylval.name = strdup(yytext);
+                        return INTEGER_LITERAL;
+                    }
+
+'{SingleStringCharacter}'   {
+                        stepLocation();
+                        yylval.name = strdup(yytext);
+                        return CHARACTER_LITERAL;
+                    }
+
+{DecimalLiteral}    {
+                        stepLocation();
+                        yylval.name = strdup(yytext);
+                        return FLOATING_PT_LITERAL;
+                    }
+
+\"{DoubleStringCharacter}*\"    {
+                        stepLocation();
+                        yylval.name = strdup(yytext);
+                        return STRING_LITERAL;
+                    }
+
+{FixedPointLiteral} {
+                        stepLocation();
+                        yylval.name = strdup(yytext);
+                        return FIXED_PT_LITERAL;
+                    }
+
+{MultiLineComment}  {
+                        /* MultiLineComment */
+                        for (char* s = yytext; *s; ++s)
+                        {
+                            if (*s == '\n')
+                            {
+                                ++yylloc.last_line;
+                                yylloc.last_column = 0;
+                            }
+                            else
+                            {
+                                ++yylloc.last_column;
+                            }
+                        }
+                        if (strncmp(yytext, "/**", 3) == 0)
+                        {
+                            /* Javadoc style comment */
+                            yylval.name = strdup(yytext);
+                            return JAVADOC;
+                        }
+                    }
+
+{SingleLineComment} {
+                        /* SingleLineComment */
+                        int c;
+
+                        do
+                        {
+                            c = yyinput();
+                        } while (c != '\n' && c != '\r' && c != EOF);
+                        ++yylloc.last_line;
+                        yylloc.last_column = 0;
+                    }
+
+{PoundSign}         {
+                        stepLocation();
+                        poundMode = true;
+                        return POUND_SIGN;
+                    }
+
+.                   {
+                        stepLocation();
+                        return (int) yytext[0];
+                    }
+
+%%
diff --git a/include/esidl.h b/include/esidl.h
new file mode 100644
--- /dev/null
+++ b/include/esidl.h
@@ -0,0 +1,5 @@
+/* A dummy header file containing no information; just to keep
+ * the compiler satisfied with unchanged lexer
+ */
+
+
diff --git a/include/lexer.h b/include/lexer.h
new file mode 100644
--- /dev/null
+++ b/include/lexer.h
@@ -0,0 +1,10 @@
+/* A glue header file for the DDI bindings to the flex-generated Web IDL scanner */
+
+#ifndef LEXER_H_INCL
+#define LEXER_H_INCL
+
+#include "esidl.h"
+#include "parser.h"
+#include "lex.yy.h"
+
+#endif
diff --git a/include/parser.h b/include/parser.h
new file mode 100644
--- /dev/null
+++ b/include/parser.h
@@ -0,0 +1,99 @@
+/*
+ * This header file contains necessary definitions to compile the lexer, 
+ * and to provide information for FFI bindings.
+ */
+
+#ifndef PARSER_H_INCL
+#define PARSER_H_INCL
+
+/* Numeric values for tokens the lexer returns */
+
+#define ANY 0x70001001
+#define ATTRIBUTE 0x70001002
+#define BOOLEAN 0x70001003
+#define CHAR 0x70001004
+#define CONST 0x70001005
+#define DOUBLE 0x70001006
+#define EOL 0x70001007 
+#define EXCEPTION 0x70001008
+#define FALSE 0x70001009
+#define FIXED 0x70001010
+#define FLOAT 0x70001011
+#define GETRAISES 0x70001012
+#define IN 0x70001013
+#define INOUT 0x70001014
+#define INTERFACE 0x70001015
+#define LONG 0x70001016
+#define MODULE 0x70001017
+#define MULTIPLE 0x70001018
+#define NATIVE 0x70001019
+#define OBJECT 0x70001020
+#define OCTET 0x70001021
+#define ONEWAY 0x70001022
+#define OUT 0x70001023
+#define RAISES 0x70001024
+#define READONLY 0x70001025
+#define SETRAISES 0x70001026
+#define SEQUENCE 0x70001027
+#define SHORT 0x70001028
+#define STRING 0x70001029
+#define STRUCT 0x70001030
+#define TRUE 0x70001031
+#define TYPEDEF 0x70001032
+#define UNSIGNED 0x70001033
+#define VALUETYPE 0x70001034
+#define VOID 0x70001035
+#define WCHAR 0x70001036
+#define WSTRING 0x70001037
+
+#define OP_SCOPE 0x70001101
+#define OP_SHL 0x70001102
+#define OP_SHR 0x70001103
+
+#define POUND_SIGN 0x70001201
+#define PRAGMA_ID 0x70001202
+
+#define IDENTIFIER 0x70001301
+#define INTEGER_LITERAL 0x70001302
+#define CHARACTER_LITERAL 0x70001303
+#define WIDE_CHARACTER_LITERAL 0x70001304
+#define FLOATING_PT_LITERAL 0x70001305
+#define STRING_LITERAL 0x70001306
+#define WIDE_STRING_LITERAL 0x70001307
+#define FIXED_PT_LITERAL 0x70001308
+
+#define JAVADOC 0x70001401
+
+/* Other structures and constants definitions */
+
+typedef struct yyltype {
+  int first_line;
+  int first_column;
+  int last_line;
+  int last_column;
+} yyltype;
+
+#define YYLTYPE yyltype
+
+typedef struct tokval {
+  char *name;
+} tokval;
+
+extern YYLTYPE yylloc, *p_yylloc;
+extern tokval  yylval, *p_yylval;
+
+#define true 1
+#define false 0
+#define bool int
+
+#define YY_USER_INIT {\
+	yylval.name = NULL;\
+	yylloc.first_line = 1;\
+	yylloc.first_column = yylloc.last_line = yylloc.last_column = 0;\
+	p_yylloc = &yylloc;\
+	p_yylval = &yylval;\
+}
+
+int yyinput (void);
+
+#endif
diff --git a/webidl.cabal b/webidl.cabal
new file mode 100644
--- /dev/null
+++ b/webidl.cabal
@@ -0,0 +1,65 @@
+Name:           webidl
+Version:        0.1
+Author:         Dmitry Golubovsky
+Maintainer:     Dmitry Golubovsky <golubovsky@gmail.com>
+License:        BSD3
+License-File:   LICENSE
+Stability:      Experimental
+Category:       Language
+
+Synopsis:       Parser and Pretty Printer for the Web IDL Language
+Description:    Web IDL is a dialect of OMG IDL used by the Web App group to specify
+                component interfaces of Web applications. See also:
+                .
+                <http://www.w3.org/TR/WebIDL/> - working draft of the specification
+                .
+                <http://www.w3.org/2008/webapps/wiki/Main_Page> - Web App group wiki
+                .
+                <http://code.google.com/p/es-operating-system/> - an experimental
+                Google - Nintendo project from which the lexer/parser files for Web IDL
+                are borrowed.
+                .
+                The package provides a Web IDL parsing\/pretty-printing library, and
+                the two executable programs:
+                .
+                * @idltestlex@: a debugging program which reads a Web IDL source
+                from its standard input, and prints the list of tokens in raw format,
+                as returned from the lexer.
+                .
+                * @idlppr@: a debugging program which reads a Web IDL source
+                from its standard input, parses, and pretty-prints it on its
+                standard output. Non-JavaDoc comments, and preprocessor directives
+                that the input might contain will not appear in the output. 
+                The program may be used to test the parser and pretty printer 
+                in the way that when @idlppr@ reads a pretty-printed Web IDL source, 
+                the output should be identical to the input. 
+                
+
+Build-Type:     Custom
+Build-Depends:  base >= 4.0.0 && < 5.0, utf8-env, utf8-string, 
+                cpphs, bytestring >= 0.9, LEXER, HSFFIG >= 1.1, 
+                parsec >= 2.0 && < 3.0, pretty >= 1.0
+Extra-source-files: cbits/lexer.ll include/esidl.h include/lexer.h include/parser.h
+                    cbits/Makefile
+
+Exposed-modules: Language.WebIDL.Lexer, Language.WebIDL.Parser, Language.WebIDL.Syntax,
+                 Language.WebIDL.PrettyPrint, Language.WebIDL
+
+Executable:     idlppr
+Main-is:        IdlPpr.hs
+Hs-source-dirs: .
+Include-dirs:   include
+Includes:       esidl.h parser.h lex.yy.h lexer.h
+C-sources:      cbits/lexer.c cbits/lex.yy.c
+Other-modules:  Language.WebIDL.Lexer, Language.WebIDL.Parser, Language.WebIDL.Syntax,
+                Language.WebIDL.PrettyPrint
+
+Executable:     idltestlex
+Main-is:        TestLex.hs
+Hs-source-dirs: .
+Include-dirs:   include
+Includes:       esidl.h parser.h lex.yy.h lexer.h
+C-sources:      cbits/lexer.c cbits/lex.yy.c
+Other-modules:  Language.WebIDL.Lexer
+
+
