forked from osmocom/wireshark
200 lines
7.3 KiB
Plaintext
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
|