wireshark/epan/protobuf_lang_scanner.l

200 lines
7.3 KiB
Plaintext

%top {
/* Include this before everything else, for various large-file definitions */
#include "config.h"
}
/*
* We want a reentrant scanner.
*/
%option reentrant
/*
* We want to generate code that can be used by a reentrant parser
* generated by Bison or Berkeley YACC.
*/
%option bison-bridge
/*
* We don't read interactively from the terminal.
*/
%option never-interactive
/*
* We want to stop processing when we get to the end of the input.
*/
%option noyywrap
/*
* The type for the state we keep for the scanner (and parser).
*/
%option extra-type="protobuf_lang_state_t *"
/*
* Prefix scanner routines with "protobuf_lang" rather than "yy", so this scanner
* can coexist with other scanners.
*/
%option prefix="protobuf_lang"
/*
* We have to override the memory allocators so that we don't get
* "unused argument" warnings from the yyscanner argument (which
* we don't use, as we have a global memory allocator).
*
* We provide, as macros, our own versions of the routines generated by Flex,
* which just call malloc()/realloc()/free() (as the Flex versions do),
* discarding the extra argument.
*/
%option noyyalloc
%option noyyrealloc
%option noyyfree
%option yylineno
%option noinput
%option nounput
%{
/* protobuf_lang_scanner.l
*
* C Protocol Buffers Language Lexer (for *.proto files)
* Copyright 2019, Huang Qiangxiong <qiangxiong.huang@qq.com>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include "protobuf_lang_tree.h"
#include "protobuf_lang.h"
/*
* Disable diagnostics in the code generated by Flex.
*/
DIAG_OFF_FLEX
/*
* Sleazy hack to suppress compiler warnings in yy_fatal_error().
*/
#define YY_EXIT_FAILURE ((void)yyscanner, 2)
/*
* Macros for the allocators, to discard the extra argument.
*/
#define protobuf_langalloc(size, yyscanner) (void *)malloc(size)
#define protobuf_langrealloc(ptr, size, yyscanner) (void *)realloc((char *)(ptr), (size))
#define protobuf_langfree(ptr, yyscanner) free((char *)ptr)
int old_status;
/* error handling function defined in bison (*.y) file */
extern void
protobuf_langerrorv(void* yyscanner, protobuf_lang_state_t *state, const char *fmt, ...);
/* duplicate the text and keep the pointer in parser state for freeing later automatically */
static gchar*
strdup_and_store(void* yyscanner, const char* text);
%}
%x COMMENT
%%
/* operations or symbols (PT_ means PBL Token) */
\" return PT_QUOTE;
"(" return PT_LPAREN;
")" return PT_RPAREN;
"[" return PT_LBRACKET;
"]" return PT_RBRACKET;
"{" return PT_LCURLY;
"}" return PT_RCURLY;
"==" return PT_EQUAL;
"!=" return PT_NOTEQUAL;
"<>" return PT_NOTEQUAL2;
">=" return PT_GEQUAL;
"<=" return PT_LEQUAL;
"+=" return PT_ASSIGN_PLUS;
"=" return PT_ASSIGN;
"+" return PT_PLUS;
"-" return PT_MINUS;
"*" return PT_MULTIPLY;
"/" return PT_DIV;
"||" return PT_LOGIC_OR;
"|" return PT_OR;
"&&" return PT_LOGIC_AND;
"&" return PT_AND;
"!" return PT_NOT;
"~" return PT_NEG;
"^" return PT_XOR;
"<<" return PT_SHL;
">>" return PT_SHR;
"%" return PT_PERCENT;
"$" return PT_DOLLAR;
"?" return PT_COND;
";" return PT_SEMICOLON;
"." return PT_DOT;
"," return PT_COMMA;
":" return PT_COLON;
"<" return PT_LESS;
">" return PT_GREATER;
/* key words */
syntax yylval->sval = strdup_and_store(yyscanner, yytext); return PT_SYNTAX;
import yylval->sval = strdup_and_store(yyscanner, yytext); return PT_IMPORT;
weak yylval->sval = strdup_and_store(yyscanner, yytext); return PT_WEAK;
public yylval->sval = strdup_and_store(yyscanner, yytext); return PT_PUBLIC;
package yylval->sval = strdup_and_store(yyscanner, yytext); return PT_PACKAGE;
option yylval->sval = strdup_and_store(yyscanner, yytext); return PT_OPTION;
required yylval->sval = strdup_and_store(yyscanner, yytext); return PT_REQUIRED;
optional yylval->sval = strdup_and_store(yyscanner, yytext); return PT_OPTIONAL;
repeated yylval->sval = strdup_and_store(yyscanner, yytext); return PT_REPEATED;
oneof yylval->sval = strdup_and_store(yyscanner, yytext); return PT_ONEOF;
map yylval->sval = strdup_and_store(yyscanner, yytext); return PT_MAP;
reserved yylval->sval = strdup_and_store(yyscanner, yytext); return PT_RESERVED;
enum yylval->sval = strdup_and_store(yyscanner, yytext); return PT_ENUM;
group yylval->sval = strdup_and_store(yyscanner, yytext); return PT_GROUP;
extend yylval->sval = strdup_and_store(yyscanner, yytext); return PT_EXTEND;
extensions yylval->sval = strdup_and_store(yyscanner, yytext); return PT_EXTENSIONS;
message yylval->sval = strdup_and_store(yyscanner, yytext); return PT_MESSAGE;
service yylval->sval = strdup_and_store(yyscanner, yytext); return PT_SERVICE;
rpc yylval->sval = strdup_and_store(yyscanner, yytext); return PT_RPC;
stream yylval->sval = strdup_and_store(yyscanner, yytext); return PT_STREAM;
returns yylval->sval = strdup_and_store(yyscanner, yytext); return PT_RETURNS;
to yylval->sval = strdup_and_store(yyscanner, yytext); return PT_TO;
/* key values */
["']proto2["'] yylval->sval = strdup_and_store(yyscanner, yytext); return PT_PROTO2;
["']proto3["'] yylval->sval = strdup_and_store(yyscanner, yytext); return PT_PROTO3;
/* intLit values */
0|[1-9][0-9]* yylval->u64val = g_ascii_strtoull(yytext, NULL, 10); return PT_DECIMALLIT;
0[0-7]* yylval->u64val = g_ascii_strtoull(yytext+1, NULL, 8); return PT_OCTALLIT;
0[xX][0-9a-fA-F]+ yylval->u64val = g_ascii_strtoull(yytext+2, NULL, 16); return PT_HEXLIT;
/* Using extended identifier because we care only about position */
[a-zA-Z0-9_][a-zA-Z0-9_.+-]* yylval->sval = strdup_and_store(yyscanner, yytext); return PT_IDENT;
\"(\\.|\"\"|[^"\n"])*\" yylval->sval = g_strndup(yytext + 1, strlen(yytext) - 2); return PT_STRLIT;
\'(\\.|\'\'|[^"\n"])*\' yylval->sval = g_strndup(yytext + 1, strlen(yytext) - 2); return PT_STRLIT;
/* comments */
"//"[^\r\n]*
"/*" { old_status = YY_START; BEGIN COMMENT; }
<COMMENT>"*/" { BEGIN old_status; }
<COMMENT>([^*]|\n)+|.
/* space & tab */
[ \t\r\n]
/* prevent flex jam */
. { protobuf_langerrorv(yyscanner, protobuf_langget_extra(yyscanner), "unexpected token in proto file!\n"); }
%%
static gchar*
strdup_and_store(void* yyscanner, const char* text) {
return pbl_store_string_token(protobuf_langget_extra(yyscanner), g_strdup(text));
}
/*
* Turn diagnostics back on, so we check the code that we've written.
*/
DIAG_ON_FLEX