From patchwork Wed May 18 19:55:01 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Gutson X-Patchwork-Id: 12352 Received: (qmail 5675 invoked by alias); 18 May 2016 19:55:15 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 5656 invoked by uid 89); 18 May 2016 19:55:14 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.5 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 spammy=SA, UD:S.A, S.A, if X-HELO: mail-oi0-f53.google.com Received: from mail-oi0-f53.google.com (HELO mail-oi0-f53.google.com) (209.85.218.53) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Wed, 18 May 2016 19:55:04 +0000 Received: by mail-oi0-f53.google.com with SMTP id x201so94648120oif.3 for ; Wed, 18 May 2016 12:55:03 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:date:message-id:subject:from:to :content-transfer-encoding; bh=EJv+7wYd8cUqn5TagEtiXBFyGLa7HyLHaVLgY8OzYcI=; b=Q8ae6jMQpOYJB5laQNdheIjARaDroLI+Mfm0F5DxM3NlQhvqxAHJ4OAZHAH6CxHLNY ti5iKX4tMR+I5ix8T4UJZSOpNZ0bpnvW5HiCxZsJ4N1W7hZDNCE/lzzmSMoHFdrFmrYN c1XuMa5VNbZ+/2Eg6Mk6SS0Oo5iKqKthcKkFNieGpNI/wQ/rAwC6ItVzXNy3/bzXPBd3 VLP3DjVkAvGnerv6FnqXO61gQXwfu+lOTZwnXx5cP/aB/VdhUTlCQQ0fghwKyRS0ixro KIyjx4SbEjSh+sKTYdXw6JfmoHTwJnmfc+YKER45xGbM4mJ+Vhg2tulj5KiPFcTgMUwM jUkQ== X-Gm-Message-State: AOPr4FVtW/naUYHTZf6BHnsZP4cvnQiU59/NjGW0IqBnp1ZCwmFaTB2zsOaAjG7y9iEjKzIFia8Hxcx1JmOh05iw MIME-Version: 1.0 X-Received: by 10.157.42.66 with SMTP id t60mr5802616ota.56.1463601301545; Wed, 18 May 2016 12:55:01 -0700 (PDT) Received: by 10.157.16.6 with HTTP; Wed, 18 May 2016 12:55:01 -0700 (PDT) Date: Wed, 18 May 2016 16:55:01 -0300 Message-ID: Subject: MI2 grammar From: Daniel Gutson To: gdb-patches , Roman Leonardo Alarcon X-IsSubscribed: yes Hi, this is a very initial version of the MI grammar for lex and yacc. This is actually a standalone application (containing C++ source code) that accepts the gdb MI output; the important part is the .y and .l files, the rest is just a C++ thing using the parser. I'm posting this here for two purposes: - so other people can use it if interested - to propose create an official grammar by adding the .l and .y files somewhere to the source tree, and keeping them updated if the grammar changes. As a side note, the quit command replies a nonconforming output since the "(gdb)" string is not included, as required in https://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-Output-Syntax.html#GDB_002fMI-Output-Syntax Thanks, Daniel. diff -Naur ./nothing/examples/example1.mi ./MI/examples/example1.mi --- ./nothing/examples/example1.mi 1969-12-31 21:00:00.000000000 -0300 +++ ./MI/examples/example1.mi 2016-05-18 14:41:26.814610554 -0300 @@ -0,0 +1,3 @@ +^done,bkpt={number="1",type="breakpoint",disp="keep",enabled="y",addr="0x00000000004007c5",func="main()",file="shuffle.cpp",fullname="/home/dgutson/sandbox/shuffle.cpp",line="223",thread-groups=["i1"],times="0",original-location="main"} +(gdb) + diff -Naur ./nothing/examples/example2.mi ./MI/examples/example2.mi --- ./nothing/examples/example2.mi 1969-12-31 21:00:00.000000000 -0300 +++ ./MI/examples/example2.mi 2016-05-18 14:41:31.994610323 -0300 @@ -0,0 +1,17 @@ +^done,OSDataTable={nr_rows="9",nr_cols="3",hdr=[{width="10",alignment="-1",col_name="col0",colhdr="Type"},{width="10",alignment="-1",col_name="col1",colhdr="Description"},{width="10",alignment="-1",col_name="col2",colhdr="Title"}],body=[item={col0="processes",col1="Listing +of all processes",col2="Processes"},item={col0="procgroups",col1="Listing +of all process groups",col2="Process +groups"},item={col0="threads",col1="Listing of all +threads",col2="Threads"},item={col0="files",col1="Listing of all file +descriptors",col2="File +descriptors"},item={col0="sockets",col1="Listing of all +internet-domain +sockets",col2="Sockets"},item={col0="shm",col1="Listing of all +shared-memory regions",col2="Shared-memory +regions"},item={col0="semaphores",col1="Listing of all +semaphores",col2="Semaphores"},item={col0="msg",col1="Listing of all +message queues",col2="Message +queues"},item={col0="modules",col1="Listing of all loaded kernel +modules",col2="Kernel modules"}]} +(gdb) + diff -Naur ./nothing/examples/example3.mi ./MI/examples/example3.mi --- ./nothing/examples/example3.mi 1969-12-31 21:00:00.000000000 -0300 +++ ./MI/examples/example3.mi 2016-05-18 15:30:56.374478158 -0300 @@ -0,0 +1,22 @@ +=thread-group-added,id="i1" +~"GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1\n" +~"Copyright (C) 2014 Free Software Foundation, Inc.\n" +~"License GPLv3+: GNU GPL version 3 or later \nThis is free software: you are free to change and redistribute it.\nThere is NO WARRANTY, to the extent permitted by law. Type \"show copying\"\nand \"show warranty\" for details.\n" +~"This GDB was configured as \"x86_64-linux-gnu\".\nType \"show configuration\" for configuration details." +~"\nFor bug reporting instructions, please see:\n" +~".\n" +~"Find the GDB manual and other documentation resources online at:\n.\n" +~"For help, type \"help\".\n" +~"Type \"apropos word\" to search for commands related to \"word\"...\n" +=cmd-param-changed,param="print object",value="on" +~"Reading symbols from ../bin/mi..." +~"(no debugging symbols found)...done.\n" +(gdb) +^done,bkpt={number="1",type="breakpoint",disp="keep",enabled="y",addr="0x0000000000403d8b",at="",thread-groups=["i1"],times="0",original-location="main"} +(gdb) +^done,OSDataTable={nr_rows="9",nr_cols="3",hdr=[{width="10",alignment="-1",col_name="col0",colhdr="Type"},{width="10",alignment="-1",col_name="col1",colhdr="Description"},{width="10",alignment="-1",col_name="col2",colhdr="Title"}],body=[item={col0="processes",col1="Listing of all processes",col2="Processes"},item={col0="procgroups",col1="Listing of all process groups",col2="Process groups"},item={col0="threads",col1="Listing of all threads",col2="Threads"},item={col0="files",col1="Listing of all file descriptors",col2="File descriptors"},item={col0="sockets",col1="Listing of all internet-domain sockets",col2="Sockets"},item={col0="shm",col1="Listing of all shared-memory regions",col2="Shared-memory regions"},item={col0="semaphores",col1="Listing of all semaphores",col2="Semaphores"},item={col0="msg",col1="Listing of all message queues",col2="Message queues"},item={col0="modules",col1="Listing of all loaded kernel modules",col2="Kernel modules"}]} +(gdb) +^done,OSDataTable={nr_rows="9",nr_cols="3",hdr=[{width="10",alignment="-1",col_name="col0",colhdr="Type"},{width="10",alignment="-1",col_name="col1",colhdr="Description"},{width="10",alignment="-1",col_name="col2",colhdr="Title"}],body=[item={col0="processes",col1="Listing of all processes",col2="Processes"},item={col0="procgroups",col1="Listing of all process groups",col2="Process groups"},item={col0="threads",col1="Listing of all threads",col2="Threads"},item={col0="files",col1="Listing of all file descriptors",col2="File descriptors"},item={col0="sockets",col1="Listing of all internet-domain sockets",col2="Sockets"},item={col0="shm",col1="Listing of all shared-memory regions",col2="Shared-memory regions"},item={col0="semaphores",col1="Listing of all semaphores",col2="Semaphores"},item={col0="msg",col1="Listing of all message queues",col2="Message queues"},item={col0="modules",col1="Listing of all loaded kernel modules",col2="Kernel modules"}]} +(gdb) +&"quit\n" +(gdb) diff -Naur ./nothing/main.cpp ./MI/main.cpp --- ./nothing/main.cpp 1969-12-31 21:00:00.000000000 -0300 +++ ./MI/main.cpp 2016-05-18 16:42:18.510287243 -0300 @@ -0,0 +1,50 @@ +/* + Main function. + Copyright (C) 2016 Roman Alarcon, Taller Technologies S.A. + + 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; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include +#include +#include "MIParserController.h" + +int main(int argc, char **argv) +{ + int ret = EXIT_SUCCESS; + + std::clog << "mi parser - v0.2" << std::endl; + + MIParserController controller; + + switch(argc) + { + case 1: + controller.runOverStdIn(); + break; + + case 2: + controller.runOverFile(argv[1]); + break; + + default: + std::cerr << "Usage: " << argv[0] << " [input-file]" << std::endl; + ret = EXIT_FAILURE; + } + + if(ret == EXIT_SUCCESS) + std::cout << "DONE." << std::endl; + + return ret; +} diff -Naur ./nothing/Makefile ./MI/Makefile --- ./nothing/Makefile 1969-12-31 21:00:00.000000000 -0300 +++ ./MI/Makefile 2016-05-18 13:54:30.000000000 -0300 @@ -0,0 +1,36 @@ +CC=g++ +CFLAGS=-c -Wno-write-strings -Wreturn-type +LDFLAGS= +SOURCES=MIFlexScanner.cpp MIBisonParser.cpp MIParserController.cpp main.cpp +OBJECTS=$(SOURCES:.cpp=.o) +EXECUTABLE_PATH=../bin +EXECUTABLE="$(EXECUTABLE_PATH)/mi" +LIBPATH= +INCPATH= +LIBS= + +all: $(SOURCES) $(EXECUTABLE) + +clean: + rm -f $(EXECUTABLE) + rm -f $(OBJECTS) + rm -f *.cpp~ + rm -f *.h~ + rm -f MIFlexScanner.cpp MIBisonParser.cpp MIBisonParser.h + +$(EXECUTABLE): $(OBJECTS) + @if [ ! -d "$(EXECUTABLE_PATH)" ]; then \ + mkdir "$(EXECUTABLE_PATH)"; \ + fi + $(CC) $(LDFLAGS) $(OBJECTS) -o $@ $(LIBPATH) $(LIBS) + +MIBisonParser.cpp: MIGrammar.y + bison -d MIGrammar.y + mv MIGrammar.tab.c MIBisonParser.cpp + mv MIGrammar.tab.h MIBisonParser.h + +MIFlexScanner.cpp: MILexer.l + flex -oMIFlexScanner.cpp MILexer.l + +.cpp.o: + $(CC) $(INCPATH) $(CFLAGS) $< -o $@ diff -Naur ./nothing/MIGrammar.y ./MI/MIGrammar.y --- ./nothing/MIGrammar.y 1969-12-31 21:00:00.000000000 -0300 +++ ./MI/MIGrammar.y 2016-05-18 16:35:21.378305840 -0300 @@ -0,0 +1,259 @@ +/* + MI Grammar specification. + Copyright (C) 2016 Roman Alarcon, Taller Technologies S.A. + + 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; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +%{ + +#include +#include "MIParserDelegate.h" + +/* + * "Private" variables + */ +static MIParserDelegate *_parserDelegate; + +/* + * Imported functions + */ +extern int yylex(); +extern std::string getLexLastToken(); +extern int getLexLineNumber(); +extern int getLexColumnNumber(); + +/* + * Exported functions + */ +void setParserDelegate(MIParserDelegate *parserDelegate); + +static int yyerror(char *s); +std::string removeDoubleQuote(const std::string& inputString); + +%} + +%union +{ + char* stringValue; +} + +%token MI_GDB +%token MI_THREAD_GROUP_ADDED +%token MI_CMD_PARAM_CHANGED +%token MI_DONE +%token MI_RUNNING +%token MI_CONNECTED +%token MI_ERROR +%token MI_EXIT +%token MI_STOPPED +%token MI_CONST +%token MI_EMPTY_TUPLE +%token MI_EMPTY_LIST +%token MI_CR +%token MI_CRLF +%token MI_NUMBER +%token MI_STRING +%token MI_IDENTIFIER + +%% + +outputList : outputList output + { + } + | output + { + } + ; + +output : outOfBandRecordList resultRecord MI_GDB + { + } + ; + +outOfBandRecordList : outOfBandRecordList outOfBandRecord + { + } + | /* EPSILON */ + { + } + ; + +outOfBandRecord : tokenOpt asyncRecord + { + } + | streamRecord + { + } + ; + +asyncRecord : '*' asyncOutput + { + } + | '+' asyncOutput + { + } + | '=' asyncOutput + { + } + ; + +asyncOutput : asyncClass + { + } + | asyncClass ',' resultList + { + } + ; + +asyncClass : MI_STOPPED + { + + } + | MI_THREAD_GROUP_ADDED + { + + } + | MI_CMD_PARAM_CHANGED + { + + } + ; + +resultRecord : tokenOpt '^' resultClass ',' resultListOpt + { + } + | /* EPSILON */ + { + } + ; + +resultClass : MI_DONE + { + } + | MI_RUNNING + { + } + | MI_CONNECTED + { + } + | MI_ERROR + { + } + | MI_EXIT + { + } + ; + +resultListOpt : resultList + { + } + | /* EPSILON */ + { + } + ; + +resultList : resultList ',' result + { + } + | result + { + } + ; + +result : MI_IDENTIFIER '=' value + { + free($1); + } + ; + +value : MI_NUMBER + { + free($1); + } + | MI_STRING + { + free($1); + } + | tuple + { + } + | list + { + } + ; + +tuple : MI_EMPTY_TUPLE + { + } + | '{' resultList '}' + { + } + ; + +list : MI_EMPTY_LIST + { + } + | '[' valueList ']' + { + } + | '[' resultList ']' + { + } + ; + +valueList : valueList ',' value + { + } + | value + { + } + ; + +streamRecord : '~' MI_STRING + { + free($2); + } + | '@' MI_STRING + { + free($2); + } + | '&' MI_STRING + { + free($2); + } + ; + +tokenOpt : MI_NUMBER + { + free($1); + } + | /* EPSILON */ + { + } + ; + +%% + +void setParserDelegate(MIParserDelegate *parserDelegate) +{ + _parserDelegate = parserDelegate; +} + +int yyerror(char *s) +{ + _parserDelegate->notifySyntaxError(getLexLastToken()); + + return 0; +} diff -Naur ./nothing/MILexer.l ./MI/MILexer.l --- ./nothing/MILexer.l 1969-12-31 21:00:00.000000000 -0300 +++ ./MI/MILexer.l 2016-05-18 16:43:23.558284342 -0300 @@ -0,0 +1,135 @@ +/* + MI Scanner specification. + Copyright (C) 2016 Roman Alarcon, Taller Technologies S.A. + + 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; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +%{ + +#include +#include +#include +#include "MIBisonParser.h" + +/* + * "Private" variables + */ +static std::string _lastToken; + +/* + * Functions able to be accessed from outside + */ +int setInputFile(const char * filename); +std::string getLexLastToken(); + +/* + * "Private" functions + */ +static void updateLastToken(const char * token); +static void skipSingleLineComment(); + +%} + +digit [0-9] +letter [A-Za-z_\-] +no_quote_or_backslash [^\"\\] +utf8char \\(u|U)[0-9A-Fa-f]+ +escapechar \\[^uU] +string \"({no_quote_or_backslash}|{utf8char}|{escapechar})*\" +identifier {letter}({letter}|{digit})* +number (0|[1-9]{digit}*) + +%% + +[\t\r\n ]+ {} +"(gdb)" { updateLastToken(yytext); return MI_GDB; } +"thread-group-added" { updateLastToken(yytext); return MI_THREAD_GROUP_ADDED; } +"cmd-param-changed" { updateLastToken(yytext); return MI_CMD_PARAM_CHANGED; } +"done" { updateLastToken(yytext); return MI_DONE; } +"running" { updateLastToken(yytext); return MI_RUNNING; } +"connected" { updateLastToken(yytext); return MI_CONNECTED; } +"error" { updateLastToken(yytext); return MI_ERROR; } +"exit" { updateLastToken(yytext); return MI_EXIT; } +"stopped" { updateLastToken(yytext); return MI_STOPPED; } +"{}" { updateLastToken(yytext); return MI_EMPTY_TUPLE; } +"[]" { updateLastToken(yytext); return MI_EMPTY_LIST; } + +{string} { + yylval.stringValue = strdup(yytext); + updateLastToken(yytext); + return MI_STRING; + } + +{number} { + yylval.stringValue = strdup(yytext); + updateLastToken(yytext); + return MI_NUMBER; + } + +{identifier} { + yylval.stringValue = strdup(yytext); + updateLastToken(yytext); + return MI_IDENTIFIER; + } + +. { + updateLastToken((std::string(&yytext[0], 1)).c_str()); + return yytext[0]; + } + +%% + +/** + * setInputFile: sets the file to be scanned + * Return values: 0 means OK, file is opened to read. 1 means error. + */ +int setInputFile(const char* filename) +{ + assert(filename != NULL); + + if (filename[0] != 0) + yyin = std::fopen(filename, "r"); + else + yyin = stdin; + return (yyin != NULL); +} + +/** + * getLexLastToken: returns the last token read + */ +std::string getLexLastToken() +{ + return _lastToken; +} + +/** + * + */ +static void updateLastToken(const char* token) +{ + _lastToken = std::string(yytext); + + // Uncomment out to see list of tokens + // std::printf("Token '%s'\n", _lastToken.c_str()); +} + +/** + * + */ +int yywrap() +{ + return 1; +} + diff -Naur ./nothing/MIParserController.cpp ./MI/MIParserController.cpp --- ./nothing/MIParserController.cpp 1969-12-31 21:00:00.000000000 -0300 +++ ./MI/MIParserController.cpp 2016-05-18 15:48:00.710432489 -0300 @@ -0,0 +1,54 @@ +/* + MIParserController - Wrapper for C-based parser + Copyright (C) 2016 Roman Alarcon, Taller Technologies S.A. + + 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; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include +#include "MIParserController.h" + +extern int yyparse(); +extern int setInputFile(const char * filename); +void setParserDelegate(MIParserDelegate *parserDelegate); + + +MIParserController::MIParserController() +{ + setParserDelegate(this); +} + +MIParserController::~MIParserController() +{ +} + +void MIParserController::runOverFile(const std::string& inputFile) +{ + setInputFile(inputFile.c_str()); + if(yyparse() == 0) + { + std::cout << "Parsing was successful." << std::endl; + } +} + +void MIParserController::runOverStdIn() +{ + runOverFile(std::string()); +} + +void MIParserController::notifySyntaxError(const std::string& token) +{ + std::cerr << "Error: unexpected token '" << token << "'" << std::endl; +} + diff -Naur ./nothing/MIParserController.h ./MI/MIParserController.h --- ./nothing/MIParserController.h 1969-12-31 21:00:00.000000000 -0300 +++ ./MI/MIParserController.h 2016-05-18 15:46:15.706437171 -0300 @@ -0,0 +1,38 @@ +/* + MIParserController - Wrapper for C-based parser + Copyright (C) 2016 Roman Alarcon, Taller Technologies S.A. + + 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; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef __MIPARSERCONTROLLER_H +#define __MIPARSERCONTROLLER_H + +#include "MIParserDelegate.h" + +class MIParserController: private MIParserDelegate +{ +public: + MIParserController(); + ~MIParserController(); + + void runOverFile(const std::string& inputFile); + void runOverStdIn(); + +private: + virtual void notifySyntaxError(const std::string& token); +}; + +#endif + diff -Naur ./nothing/MIParserDelegate.h ./MI/MIParserDelegate.h --- ./nothing/MIParserDelegate.h 1969-12-31 21:00:00.000000000 -0300 +++ ./MI/MIParserDelegate.h 2016-05-18 14:39:36.000000000 -0300 @@ -0,0 +1,30 @@ +/* + MIParserDelegate - Callbacks declarations + Copyright (C) 2016 Roman Alarcon, Taller Technologies S.A. + + 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; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef __MIPARSERDELEGATE_H +#define __MIPARSERDELEGATE_H + +#include + +class MIParserDelegate +{ +public: + virtual void notifySyntaxError(const std::string& token) = 0; +}; + +#endif