/* * Scanner for the PCIE-AER grammar. * * Copyright (c) 2009 by Intel Corp. * Author: Huang Ying * * Based on mce.lex of mce-inject, which is written by Andi Kleen * . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; version 2 of the * License. */ %{ #define _GNU_SOURCE 1 #include #include #include "aer.h" #include "aer.tab.h" #include "util.h" int yylineno; static int lookup_symbol(const char *); %} %option nounput HEXC [0-9a-fA-F] %% #.*\n /* comment */; \n ++yylineno; ({HEXC}{4}:)?{HEXC}{2}:{HEXC}{2}\.{HEXC} { yylval.str = strdup(yytext); return PCI_ID_STR; } 0x{HEXC}+ | 0[0-7]+ | [0-9]+ yylval.num = strtoull(yytext, NULL, 0); return NUMBER; [:{}<>] return yytext[0]; [_a-zA-Z][_a-zA-Z0-9]* return lookup_symbol(yytext); [ \t]+ /* white space */; . yyerror("Unrecognized character '%s'", yytext); %% /* Keyword handling */ static struct key { const char *name; int tok; int32_t val; } keys[] = { #define KEY(x) { #x, x } #define ALIAS(x, y) { #x, y } #define KEYVAL(x,v) { #x, x, v } KEY(AER), KEY(DOMAIN), KEY(BUS), KEY(DEV), KEY(FN), KEY(PCI_ID), ALIAS(ID, PCI_ID), KEY(UNCOR_STATUS), ALIAS(UNCOR, UNCOR_STATUS), ALIAS(UNCORRECTABLE, UNCOR_STATUS), KEY(COR_STATUS), ALIAS(COR, COR_STATUS), ALIAS(CORRECTABLE, COR_STATUS), KEY(HEADER_LOG), ALIAS(HL, HEADER_LOG), KEYVAL(TRAIN,PCI_ERR_UNC_TRAIN), KEYVAL(DLP, PCI_ERR_UNC_DLP), KEYVAL(POISON_TLP, PCI_ERR_UNC_POISON_TLP), KEYVAL(FCP, PCI_ERR_UNC_FCP), KEYVAL(COMP_TIME, PCI_ERR_UNC_COMP_TIME), KEYVAL(COMP_ABORT, PCI_ERR_UNC_COMP_ABORT), KEYVAL(UNX_COMP, PCI_ERR_UNC_UNX_COMP), KEYVAL(RX_OVER, PCI_ERR_UNC_RX_OVER), KEYVAL(MALF_TLP, PCI_ERR_UNC_MALF_TLP), KEYVAL(ECRC, PCI_ERR_UNC_ECRC), KEYVAL(UNSUP, PCI_ERR_UNC_UNSUP), KEYVAL(RCVR, PCI_ERR_COR_RCVR), KEYVAL(BAD_TLP, PCI_ERR_COR_BAD_TLP), KEYVAL(BAD_DLLP, PCI_ERR_COR_BAD_DLLP), KEYVAL(REP_ROLL, PCI_ERR_COR_REP_ROLL), KEYVAL(REP_TIMER, PCI_ERR_COR_REP_TIMER), }; static int cmp_key(const void *av, const void *bv) { const struct key *a = av; const struct key *b = bv; return strcasecmp(a->name, b->name); } static int lookup_symbol(const char *name) { struct key *k; struct key key; key.name = name; k = bsearch(&key, keys, ARRAY_SIZE(keys), sizeof(struct key), cmp_key); if (k != NULL) { yylval.num = k->val; return k->tok; } return SYMBOL; } static void init_lex(void) { qsort(keys, ARRAY_SIZE(keys), sizeof(struct key), cmp_key); } static char **argv; char *filename = ""; int yywrap(void) { if (*argv == NULL) return 1; filename = *argv; yyin = fopen(filename, "r"); ERROR_EXIT_ON(!yyin, "Can not open: %s", filename); argv++; return 0; } int parse_data(char **av) { init_lex(); argv = av; if (*argv) yywrap(); return yyparse(); }