clex.py revision 2632
12632Sstever@eecs.umich.edu# ----------------------------------------------------------------------
22632Sstever@eecs.umich.edu# clex.py
32632Sstever@eecs.umich.edu#
42632Sstever@eecs.umich.edu# A lexer for ANSI C.
52632Sstever@eecs.umich.edu# ----------------------------------------------------------------------
62632Sstever@eecs.umich.edu
72632Sstever@eecs.umich.eduimport lex
82632Sstever@eecs.umich.edu
92632Sstever@eecs.umich.edu# Reserved words
102632Sstever@eecs.umich.edureserved = (
112632Sstever@eecs.umich.edu    'AUTO', 'BREAK', 'CASE', 'CHAR', 'CONST', 'CONTINUE', 'DEFAULT', 'DO', 'DOUBLE',
122632Sstever@eecs.umich.edu    'ELSE', 'ENUM', 'EXTERN', 'FLOAT', 'FOR', 'GOTO', 'IF', 'INT', 'LONG', 'REGISTER',
132632Sstever@eecs.umich.edu    'RETURN', 'SHORT', 'SIGNED', 'SIZEOF', 'STATIC', 'STRUCT', 'SWITCH', 'TYPEDEF',
142632Sstever@eecs.umich.edu    'UNION', 'UNSIGNED', 'VOID', 'VOLATILE', 'WHILE',
152632Sstever@eecs.umich.edu    )
162632Sstever@eecs.umich.edu
172632Sstever@eecs.umich.edutokens = reserved + (
182632Sstever@eecs.umich.edu    # Literals (identifier, integer constant, float constant, string constant, char const)
192632Sstever@eecs.umich.edu    'ID', 'TYPEID', 'ICONST', 'FCONST', 'SCONST', 'CCONST',
202632Sstever@eecs.umich.edu
212632Sstever@eecs.umich.edu    # Operators (+,-,*,/,%,|,&,~,^,<<,>>, ||, &&, !, <, <=, >, >=, ==, !=)
222632Sstever@eecs.umich.edu    'PLUS', 'MINUS', 'TIMES', 'DIVIDE', 'MOD',
232632Sstever@eecs.umich.edu    'OR', 'AND', 'NOT', 'XOR', 'LSHIFT', 'RSHIFT',
242632Sstever@eecs.umich.edu    'LOR', 'LAND', 'LNOT',
252632Sstever@eecs.umich.edu    'LT', 'LE', 'GT', 'GE', 'EQ', 'NE',
262632Sstever@eecs.umich.edu
272632Sstever@eecs.umich.edu    # Assignment (=, *=, /=, %=, +=, -=, <<=, >>=, &=, ^=, |=)
282632Sstever@eecs.umich.edu    'EQUALS', 'TIMESEQUAL', 'DIVEQUAL', 'MODEQUAL', 'PLUSEQUAL', 'MINUSEQUAL',
292632Sstever@eecs.umich.edu    'LSHIFTEQUAL','RSHIFTEQUAL', 'ANDEQUAL', 'XOREQUAL', 'OREQUAL',
302632Sstever@eecs.umich.edu
312632Sstever@eecs.umich.edu    # Increment/decrement (++,--)
322632Sstever@eecs.umich.edu    'PLUSPLUS', 'MINUSMINUS',
332632Sstever@eecs.umich.edu
342632Sstever@eecs.umich.edu    # Structure dereference (->)
352632Sstever@eecs.umich.edu    'ARROW',
362632Sstever@eecs.umich.edu
372632Sstever@eecs.umich.edu    # Conditional operator (?)
382632Sstever@eecs.umich.edu    'CONDOP',
392632Sstever@eecs.umich.edu
402632Sstever@eecs.umich.edu    # Delimeters ( ) [ ] { } , . ; :
412632Sstever@eecs.umich.edu    'LPAREN', 'RPAREN',
422632Sstever@eecs.umich.edu    'LBRACKET', 'RBRACKET',
432632Sstever@eecs.umich.edu    'LBRACE', 'RBRACE',
442632Sstever@eecs.umich.edu    'COMMA', 'PERIOD', 'SEMI', 'COLON',
452632Sstever@eecs.umich.edu
462632Sstever@eecs.umich.edu    # Ellipsis (...)
472632Sstever@eecs.umich.edu    'ELLIPSIS',
482632Sstever@eecs.umich.edu    )
492632Sstever@eecs.umich.edu
502632Sstever@eecs.umich.edu# Completely ignored characters
512632Sstever@eecs.umich.edut_ignore           = ' \t\x0c'
522632Sstever@eecs.umich.edu
532632Sstever@eecs.umich.edu# Newlines
542632Sstever@eecs.umich.edudef t_NEWLINE(t):
552632Sstever@eecs.umich.edu    r'\n+'
562632Sstever@eecs.umich.edu    t.lineno += t.value.count("\n")
572632Sstever@eecs.umich.edu
582632Sstever@eecs.umich.edu# Operators
592632Sstever@eecs.umich.edut_PLUS             = r'\+'
602632Sstever@eecs.umich.edut_MINUS            = r'-'
612632Sstever@eecs.umich.edut_TIMES            = r'\*'
622632Sstever@eecs.umich.edut_DIVIDE           = r'/'
632632Sstever@eecs.umich.edut_MOD              = r'%'
642632Sstever@eecs.umich.edut_OR               = r'\|'
652632Sstever@eecs.umich.edut_AND              = r'&'
662632Sstever@eecs.umich.edut_NOT              = r'~'
672632Sstever@eecs.umich.edut_XOR              = r'^'
682632Sstever@eecs.umich.edut_LSHIFT           = r'<<'
692632Sstever@eecs.umich.edut_RSHIFT           = r'>>'
702632Sstever@eecs.umich.edut_LOR              = r'\|\|'
712632Sstever@eecs.umich.edut_LAND             = r'&&'
722632Sstever@eecs.umich.edut_LNOT             = r'!'
732632Sstever@eecs.umich.edut_LT               = r'<'
742632Sstever@eecs.umich.edut_GT               = r'>'
752632Sstever@eecs.umich.edut_LE               = r'<='
762632Sstever@eecs.umich.edut_GE               = r'>='
772632Sstever@eecs.umich.edut_EQ               = r'=='
782632Sstever@eecs.umich.edut_NE               = r'!='
792632Sstever@eecs.umich.edu
802632Sstever@eecs.umich.edu# Assignment operators
812632Sstever@eecs.umich.edu
822632Sstever@eecs.umich.edut_EQUALS           = r'='
832632Sstever@eecs.umich.edut_TIMESEQUAL       = r'\*='
842632Sstever@eecs.umich.edut_DIVEQUAL         = r'/='
852632Sstever@eecs.umich.edut_MODEQUAL         = r'%='
862632Sstever@eecs.umich.edut_PLUSEQUAL        = r'\+='
872632Sstever@eecs.umich.edut_MINUSEQUAL       = r'-='
882632Sstever@eecs.umich.edut_LSHIFTEQUAL      = r'<<='
892632Sstever@eecs.umich.edut_RSHIFTEQUAL      = r'>>='
902632Sstever@eecs.umich.edut_ANDEQUAL         = r'&='
912632Sstever@eecs.umich.edut_OREQUAL          = r'\|='
922632Sstever@eecs.umich.edut_XOREQUAL         = r'^='
932632Sstever@eecs.umich.edu
942632Sstever@eecs.umich.edu# Increment/decrement
952632Sstever@eecs.umich.edut_PLUSPLUS         = r'\+\+'
962632Sstever@eecs.umich.edut_MINUSMINUS       = r'--'
972632Sstever@eecs.umich.edu
982632Sstever@eecs.umich.edu# ->
992632Sstever@eecs.umich.edut_ARROW            = r'->'
1002632Sstever@eecs.umich.edu
1012632Sstever@eecs.umich.edu# ?
1022632Sstever@eecs.umich.edut_CONDOP           = r'\?'
1032632Sstever@eecs.umich.edu
1042632Sstever@eecs.umich.edu# Delimeters
1052632Sstever@eecs.umich.edut_LPAREN           = r'\('
1062632Sstever@eecs.umich.edut_RPAREN           = r'\)'
1072632Sstever@eecs.umich.edut_LBRACKET         = r'\['
1082632Sstever@eecs.umich.edut_RBRACKET         = r'\]'
1092632Sstever@eecs.umich.edut_LBRACE           = r'\{'
1102632Sstever@eecs.umich.edut_RBRACE           = r'\}'
1112632Sstever@eecs.umich.edut_COMMA            = r','
1122632Sstever@eecs.umich.edut_PERIOD           = r'\.'
1132632Sstever@eecs.umich.edut_SEMI             = r';'
1142632Sstever@eecs.umich.edut_COLON            = r':'
1152632Sstever@eecs.umich.edut_ELLIPSIS         = r'\.\.\.'
1162632Sstever@eecs.umich.edu
1172632Sstever@eecs.umich.edu# Identifiers and reserved words
1182632Sstever@eecs.umich.edu
1192632Sstever@eecs.umich.edureserved_map = { }
1202632Sstever@eecs.umich.edufor r in reserved:
1212632Sstever@eecs.umich.edu    reserved_map[r.lower()] = r
1222632Sstever@eecs.umich.edu
1232632Sstever@eecs.umich.edudef t_ID(t):
1242632Sstever@eecs.umich.edu    r'[A-Za-z_][\w_]*'
1252632Sstever@eecs.umich.edu    t.type = reserved_map.get(t.value,"ID")
1262632Sstever@eecs.umich.edu    return t
1272632Sstever@eecs.umich.edu
1282632Sstever@eecs.umich.edu# Integer literal
1292632Sstever@eecs.umich.edut_ICONST = r'\d+([uU]|[lL]|[uU][lL]|[lL][uU])?'
1302632Sstever@eecs.umich.edu
1312632Sstever@eecs.umich.edu# Floating literal
1322632Sstever@eecs.umich.edut_FCONST = r'((\d+)(\.\d+)(e(\+|-)?(\d+))? | (\d+)e(\+|-)?(\d+))([lL]|[fF])?'
1332632Sstever@eecs.umich.edu
1342632Sstever@eecs.umich.edu# String literal
1352632Sstever@eecs.umich.edut_SCONST = r'\"([^\\\n]|(\\.))*?\"'
1362632Sstever@eecs.umich.edu
1372632Sstever@eecs.umich.edu# Character constant 'c' or L'c'
1382632Sstever@eecs.umich.edut_CCONST = r'(L)?\'([^\\\n]|(\\.))*?\''
1392632Sstever@eecs.umich.edu
1402632Sstever@eecs.umich.edu# Comments
1412632Sstever@eecs.umich.edudef t_comment(t):
1422632Sstever@eecs.umich.edu    r' /\*(.|\n)*?\*/'
1432632Sstever@eecs.umich.edu    t.lineno += t.value.count('\n')
1442632Sstever@eecs.umich.edu
1452632Sstever@eecs.umich.edu# Preprocessor directive (ignored)
1462632Sstever@eecs.umich.edudef t_preprocessor(t):
1472632Sstever@eecs.umich.edu    r'\#(.)*?\n'
1482632Sstever@eecs.umich.edu    t.lineno += 1
1492632Sstever@eecs.umich.edu
1502632Sstever@eecs.umich.edudef t_error(t):
1512632Sstever@eecs.umich.edu    print "Illegal character %s" % repr(t.value[0])
1522632Sstever@eecs.umich.edu    t.skip(1)
1532632Sstever@eecs.umich.edu
1542632Sstever@eecs.umich.edulexer = lex.lex(optimize=1)
1552632Sstever@eecs.umich.eduif __name__ == "__main__":
1562632Sstever@eecs.umich.edu    lex.runmain(lexer)
1572632Sstever@eecs.umich.edu
1582632Sstever@eecs.umich.edu
1592632Sstever@eecs.umich.edu
1602632Sstever@eecs.umich.edu
1612632Sstever@eecs.umich.edu
162