packages feed

HSFFIG-1.1: programs/C_Lexer.x

{

-- This lexer file is based on the following source:
-- http://www.lysator.liu.se/c/ANSI-C-grammar-l.html
-- and converted into Alex syntax from Lex syntax by
-- Dimitry Golubovsky <dimitry@golubovsky.org>, <golubovsky@gmail.com>

-- It is expected that this lexer processes the result of
-- `gcc -E -dD' applied to a C header file, so certain assumptions
-- are made:
--
-- 1. CPP directives like #if(n)def, #if, #endif are absent in the input
-- 2. All #define directives occupy exactly one line

module C_Lexer (
    Token (..),
    AlexPosn(..),
    scanHeader
  ) where
}

%wrapper "posn"

$O  =			[0-7]
$D  =			[0-9]
$L  =			[a-zA-Z_]
$H  =			[a-fA-F0-9]

@E  =			[Ee] [\+\-]? $D+
@FS =			[fFlL]
@IS =			[uUlL]*

tokens :-
"/*"			{ tok (\p s -> TCOMM_OPEN p) }
"*/"			{ tok (\p s -> TCOMM_CLOSE p) }

"auto"			{ tok (\p s -> TKW s p) }
"break"			{ tok (\p s -> TKW s p) }
"case"			{ tok (\p s -> TKW s p) }
"char"			{ tok (\p s -> TKW s p) }
"const"			{ tok (\p s -> TKW s p) }
"__const"		{ tok (\p s -> TKW "const" p) }
"continue"		{ tok (\p s -> TKW s p) }
"default"		{ tok (\p s -> TKW s p) }
"do"			{ tok (\p s -> TKW s p) }
"double"		{ tok (\p s -> TKW s p) }
"else"			{ tok (\p s -> TKW s p) }
"enum"			{ tok (\p s -> TKW s p) }
"extern"		{ tok (\p s -> TKW s p) }
"float"			{ tok (\p s -> TKW s p) }
"for"			{ tok (\p s -> TKW s p) }
"goto"			{ tok (\p s -> TKW s p) }
"if"			{ tok (\p s -> TKW s p) }
"int"			{ tok (\p s -> TKW s p) }
"long"			{ tok (\p s -> TKW s p) }
"register"		{ tok (\p s -> TKW s p) }
"return"		{ tok (\p s -> TKW s p) }
"short"			{ tok (\p s -> TKW s p) }
"signed"		{ tok (\p s -> TKW s p) }
"__signed__"		{ tok (\p s -> TKW "signed" p)}
"inline"		{ tok (\p s -> TKW s p) }
"__inline__"            { tok (\p s -> TKW "inline" p)}
"sizeof"		{ tok (\p s -> TKW s p) }
"static"		{ tok (\p s -> TKW s p) }
"struct"		{ tok (\p s -> TKW s p) }
"switch"		{ tok (\p s -> TKW s p) }
"typedef"		{ tok (\p s -> TKW s p) }
"union"			{ tok (\p s -> TKW s p) }
"unsigned"		{ tok (\p s -> TKW s p) }
"void"			{ tok (\p s -> TKW s p) }
"volatile"		{ tok (\p s -> TKW s p) }
"while"			{ tok (\p s -> TKW s p) }
"__attribute__"		{ tok (\p s -> TKW s p) }
"__extension__"         ;
"__restrict"            ;
"__restrict__"          ;
"#define" $white+ .*	{ tok (\p s -> TKDEF s p) }
"#undef" $white+ .*     ;

$L [$L $D]*		{ tok (\p s -> TKID s p) }

0 [xX] $H+ @IS{0,3}	{ tok (\p s -> TKC_HEX s p) }
0 $D+ @IS{0,3}		{ tok (\p s -> TKC_OCT s p) }
$D+ @IS{0,3}		{ tok (\p s -> TKC_DEC s p) }
L?'(\.|[^\'])+'		{ tok (\p s -> TKC_CHAR s p) }

$D+ @E @FS{0,2}		{ tok (\p s -> TKC_EXP s p) }
$D* \. $D+ @E? @FS{0,2} { tok (\p s -> TKC_EXP s p) }
$D+ \. $D* @E? @FS{0,2}	{ tok (\p s -> TKC_EXP s p) }

L?\"(\.|[^\"])*\"	{ tok (\p s -> TKSTRING s p) }

"..."			{ tok (\p s -> TKOP s p) }
">>="			{ tok (\p s -> TKOP s p) }
"<<="			{ tok (\p s -> TKOP s p) }
"+="			{ tok (\p s -> TKOP s p) }
"-="			{ tok (\p s -> TKOP s p) }
"*="			{ tok (\p s -> TKOP s p) }
"/="			{ tok (\p s -> TKOP s p) }
"%="			{ tok (\p s -> TKOP s p) }
"&="			{ tok (\p s -> TKOP s p) }
"^="			{ tok (\p s -> TKOP s p) }
"|="			{ tok (\p s -> TKOP s p) }
">>"			{ tok (\p s -> TKOP s p) }
"<<"			{ tok (\p s -> TKOP s p) }
"++"			{ tok (\p s -> TKOP s p) }
"--"			{ tok (\p s -> TKOP s p) }
"->"			{ tok (\p s -> TKOP s p) }
"&&"			{ tok (\p s -> TKOP s p) }
"||"			{ tok (\p s -> TKOP s p) }
"<="			{ tok (\p s -> TKOP s p) }
">="			{ tok (\p s -> TKOP s p) }
"=="			{ tok (\p s -> TKOP s p) }
"!="			{ tok (\p s -> TKOP s p) }
";"			{ tok (\p s -> TKOP s p) }
("{"|"<%")		{ tok (\p s -> TKOP "{" p) }
("}"|"%>")		{ tok (\p s -> TKOP "}" p) }
","			{ tok (\p s -> TKOP s p) }
":"			{ tok (\p s -> TKOP s p) }
"="			{ tok (\p s -> TKOP s p) }
"("			{ tok (\p s -> TKOP s p) }
")"			{ tok (\p s -> TKOP s p) }
("["|"<:")		{ tok (\p s -> TKOP "[" p) }
("]"|":>")		{ tok (\p s -> TKOP "]" p) }
"."			{ tok (\p s -> TKOP s p) }
"&"			{ tok (\p s -> TKOP s p) }
"!"			{ tok (\p s -> TKOP s p) }
"~"			{ tok (\p s -> TKOP s p) }
"-"			{ tok (\p s -> TKOP s p) }
"+"			{ tok (\p s -> TKOP s p) }
"*"			{ tok (\p s -> TKOP s p) }
"/"			{ tok (\p s -> TKOP s p) }
"%"			{ tok (\p s -> TKOP s p) }
"<"			{ tok (\p s -> TKOP s p) }
">"			{ tok (\p s -> TKOP s p) }
"^"			{ tok (\p s -> TKOP s p) }
"|"			{ tok (\p s -> TKOP s p) }
"?"			{ tok (\p s -> TKOP s p) }

"#" $white+ .*		{ tok (\p s -> TKFILE s p) }

[ \t\v\n\f]		;
.			;

{

tok f p s = f p s

-- The datatype for Token

data Token = TCOMM_OPEN AlexPosn 
           | TCOMM_CLOSE AlexPosn 
           | TKDEF String AlexPosn
           | TKFILE String AlexPosn
           | TKW String AlexPosn
           | TKOP String AlexPosn
           | TKID String AlexPosn
           | TKC_EXP String AlexPosn
           | TKC_DEC String AlexPosn
           | TKC_OCT String AlexPosn
           | TKC_HEX String AlexPosn
           | TKC_CHAR String AlexPosn
           | TKSTRING String AlexPosn
           deriving (Show)

-- Access to the lexer

scanHeader str = alexScanTokens str
    
-- Token equality. Two tokens are equal if their contents
-- are equal regarding of position.

instance Eq Token where
    (==) (TCOMM_OPEN _) (TCOMM_OPEN _) = True
    (==) (TCOMM_CLOSE _) (TCOMM_CLOSE _) = True
    (==) (TKDEF s1 _) (TKDEF s2 _) = (s1 == s2)
    (==) (TKFILE s1 _) (TKFILE s2 _) = (s1 == s2)
    (==) (TKW s1 _) (TKW s2 _) = (s1 == s2)
    (==) (TKOP s1 _) (TKOP s2 _) = (s1 == s2)
    (==) (TKID s1 _) (TKID s2 _) = (s1 == s2)
    (==) (TKC_EXP s1 _) (TKC_EXP s2 _) = (s1 == s2)
    (==) (TKC_DEC s1 _) (TKC_DEC s2 _) = (s1 == s2)
    (==) (TKC_OCT s1 _) (TKC_OCT s2 _) = (s1 == s2)
    (==) (TKC_HEX s1 _) (TKC_HEX s2 _) = (s1 == s2)
    (==) (TKC_CHAR s1 _) (TKC_CHAR s2 _) = (s1 == s2)
    (==) (TKSTRING s1 _) (TKSTRING s2 _) = (s1 == s2)
    (==) _ _ = False


}