blob: 6121e4e518fee36c3aea9b43d2c23989961005d1 [file] [log] [blame]
/*
* Scanner for the PCIE-AER grammar.
*
* Copyright (c) 2009 by Intel Corp.
* Author: Huang Ying <ying.huang@intel.com>
*
* Based on mce.lex of mce-inject, which is written by Andi Kleen
* <andi.kleen@intel.com>.
*
* 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 <stdlib.h>
#include <string.h>
#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 = "<stdin>";
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();
}