Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c71fdabd authored by Casey Dahlin's avatar Casey Dahlin Committed by Gerrit Code Review
Browse files

Merge "First pass on reentrant C++-ish parser"

parents a5ec056b 9941dcc7
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -36,6 +36,8 @@ using std::set;
using std::string;
using std::vector;

ParseState *psGlobal;

static void
test_document(document_item_type* d)
{
@@ -114,7 +116,7 @@ main_import_parsed(buffer_type* statement)
{
    import_info* import = (import_info*)malloc(sizeof(import_info));
    memset(import, 0, sizeof(import_info));
    import->from = strdup(g_currentFilename);
    import->from = strdup(psGlobal->FileName().c_str());
    import->statement.lineno = statement->lineno;
    import->statement.data = strdup(statement->data);
    import->statement.extra = NULL;
+78 −12
Original line number Diff line number Diff line
#include "aidl_language.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <string>
#include <iostream>

#ifdef _WIN32
int isatty(int  fd)
{
    return (fd == 0);
using std::string;
using std::cerr;
using std::endl;

ParserCallbacks* g_callbacks = NULL; // &k_parserCallbacks;

void yylex_init(void **);
void yylex_destroy(void *);
void yyset_in(FILE *f, void *);
int yyparse(ParseState*);

ParseState::ParseState() : ParseState("") {}

ParseState::ParseState(const string& filename)
    : filename_(filename) {
  yylex_init(&scanner_);
}
#endif

#if 0
ParserCallbacks k_parserCallbacks = {
    NULL
};
#endif
ParseState::~ParseState() {
  yylex_destroy(scanner_);
}

ParserCallbacks* g_callbacks = NULL; // &k_parserCallbacks;
string ParseState::FileName() {
  return filename_;
}

string ParseState::Package() {
  return g_currentPackage;
}

void ParseState::ProcessDocument(const document_item_type& items) {
  /* The cast is not my fault. I didn't write the code on the other side. */
  /* TODO(sadmac): b/23977313 */
  g_callbacks->document((document_item_type *)&items);
}

void ParseState::ProcessImport(const buffer_type& statement) {
  /* The cast is not my fault. I didn't write the code on the other side. */
  /* TODO(sadmac): b/23977313 */
  g_callbacks->import((buffer_type *)&statement);
}

void ParseState::ReportError(const string& err) {
  /* FIXME: We're printing out the line number as -1. We used to use yylineno
   * (which was NEVER correct even before reentrant parsing). Now we'll need
   * another way.
   */
  cerr << filename_ << ":" << -1 << ": " << err << endl;
  error_ = 1;
}

bool ParseState::FoundNoErrors() {
  return error_ == 0;
}

void *ParseState::Scanner() {
  return scanner_;
}

bool ParseState::OpenFileFromDisk() {
  FILE *in = fopen(FileName().c_str(), "r");

  if (! in)
    return false;

  yyset_in(in, Scanner());
  return true;
}

int ParseState::RunParser() {
  int ret = yyparse(this);

  free((void *)g_currentPackage);
  g_currentPackage = NULL;

  if (error_)
    return 1;

  return ret;
}
+30 −6
Original line number Diff line number Diff line
#ifndef AIDL_AIDL_LANGUAGE_H_
#define AIDL_AIDL_LANGUAGE_H_

#include <string>

#include "macros.h"

typedef enum {
    NO_EXTRA_TEXT = 0,
@@ -141,12 +144,6 @@ typedef struct ParserCallbacks {

extern ParserCallbacks* g_callbacks;

// true if there was an error parsing, false otherwise
extern int g_error;

// the name of the file we're currently parsing
extern char const* g_currentFilename;

// the package name for our current file
extern char const* g_currentPackage;

@@ -157,6 +154,33 @@ typedef enum {
void init_buffer_type(buffer_type* buf, int lineno);


class ParseState {
 public:
  ParseState();
  ParseState(const std::string& filename);
  ~ParseState();

  bool OpenFileFromDisk();
  int RunParser();
  void ReportError(const std::string& err);

  bool FoundNoErrors();
  std::string FileName();
  std::string Package();
  void *Scanner();

  void ProcessDocument(const document_item_type& items);
  void ProcessImport(const buffer_type& statement);

 private:
  int error_ = 0;
  std::string filename_;
  std::string package_;
  void *scanner_ = nullptr;

  DISALLOW_COPY_AND_ASSIGN(ParseState);
};

#if __cplusplus
}
#endif
+26 −36
Original line number Diff line number Diff line
@@ -7,6 +7,13 @@

extern YYSTYPE yylval;

#ifdef _WIN32
static inline int isatty(int fd)
{
  return 0;
}
#endif

// comment and whitespace handling
// these functions save a copy of the buffer
static void begin_extra_text(unsigned lineno, which_extra_text which);
@@ -20,16 +27,18 @@ static void do_package_statement(const char* importText);

#define SET_BUFFER(t) \
    do { \
        yylval.buffer.lineno = yylineno; \
        yylval.buffer.token = (t); \
        yylval.buffer.data = strdup(yytext); \
        yylval.buffer.extra = get_extra_text(); \
        yylval->buffer.lineno = yyget_lineno(yyscanner); \
        yylval->buffer.token = (t); \
        yylval->buffer.data = strdup(yytext); \
        yylval->buffer.extra = get_extra_text(); \
    } while(0)

%}

%option yylineno
%option noyywrap
%option reentrant
%option bison-bridge

%x COPYING LONG_COMMENT

@@ -96,9 +105,9 @@ oneway { SET_BUFFER(ONEWAY); return ONEWAY; }

    /* syntax error! */
.               { printf("UNKNOWN(%s)", yytext);
                  yylval.buffer.lineno = yylineno;
                  yylval.buffer.token = IDENTIFIER;
                  yylval.buffer.data = strdup(yytext);
                  yylval->buffer.lineno = yylineno;
                  yylval->buffer.token = IDENTIFIER;
                  yylval->buffer.data = strdup(yytext);
                  return IDENTIFIER;
                }

@@ -177,36 +186,17 @@ void do_package_statement(const char* importText)

// main parse function
// ================================================
char const* g_currentFilename = NULL;
extern ParseState *psGlobal;
char const* g_currentPackage = NULL;

int yyparse(void);

int parse_aidl(char const *filename)
{
    yyin = fopen(filename, "r");
    if (yyin) {
        char const* oldFilename = g_currentFilename;
        char const* oldPackage = g_currentPackage;
        g_currentFilename = strdup(filename);

        g_error = 0;
        yylineno = 1;
        int rv = yyparse();
        if (g_error != 0) {
            rv = g_error;
        }

        free((void*)g_currentFilename);
        g_currentFilename = oldFilename;
        
        if (g_currentPackage) free((void*)g_currentPackage);
        g_currentPackage = oldPackage;
int parse_aidl(char const *filename) {
  ParseState ps(filename);
  psGlobal = &ps;

        return rv;
    } else {
  if (!ps.OpenFileFromDisk()) {
    fprintf(stderr, "aidl: unable to open file for read: %s\n", filename);
    return 1;
  }
}

  return ps.RunParser();
}
+35 −28
Original line number Diff line number Diff line
@@ -4,14 +4,24 @@
#include <stdlib.h>
#include <string.h>

int yyerror(char* errstr);
int yylex(void);
extern int yylineno;
int yyerror(ParseState* ps, char* errstr)
{
  ps->ReportError(errstr);
  return 1;
}

int yylex(lexer_type *, void *);

static int count_brackets(const char*);

#define YYLEX_PARAM ps->Scanner()

%}

%parse-param { ParseState* ps }

%pure-parser

%token IMPORT
%token PACKAGE
%token IDENTIFIER
@@ -27,8 +37,8 @@ static int count_brackets(const char*);

%%
document:
        document_items                          { g_callbacks->document($1.document_item); }
    |   headers document_items                  { g_callbacks->document($2.document_item); }
        document_items                          { ps->ProcessDocument(*$1.document_item); }
    |   headers document_items                  { ps->ProcessDocument(*$2.document_item); }
    ;

headers:
@@ -42,8 +52,8 @@ package:
    ;

imports:
        IMPORT                                  { g_callbacks->import(&($1.buffer)); }
    |   IMPORT imports                          { g_callbacks->import(&($1.buffer)); }
        IMPORT                                  { ps->ProcessImport($1.buffer); }
    |   IMPORT imports                          { ps->ProcessImport($1.buffer); }
    ;

document_items:
@@ -66,7 +76,8 @@ document_items:
                                                    }
                                                }
    | document_items error                      {
                                                    fprintf(stderr, "%s:%d: syntax error don't know what to do with \"%s\"\n", g_currentFilename,
                                                    fprintf(stderr, "%s:%d: syntax error don't know what to do with \"%s\"\n",
                                                            ps->FileName().c_str(),
                                                            $2.buffer.lineno, $2.buffer.data);
                                                    $$ = $1;
                                                }
@@ -84,19 +95,20 @@ parcelable_decl:
                                                        b->document_item.next = NULL;
                                                        b->keyword_token = $1.buffer;
                                                        b->name = $2.buffer;
                                                        b->package = g_currentPackage ? strdup(g_currentPackage) : NULL;
                                                        b->package =
                                                        strdup(ps->Package().c_str());
                                                        b->semicolon_token = $3.buffer;
                                                        b->parcelable = true;
                                                        $$.user_data = b;
                                                    }
    |   PARCELABLE ';'                              {
                                                        fprintf(stderr, "%s:%d syntax error in parcelable declaration. Expected type name.\n",
                                                                     g_currentFilename, $1.buffer.lineno);
                                                                     ps->FileName().c_str(), $1.buffer.lineno);
                                                        $$.user_data = NULL;
                                                    }
    |   PARCELABLE error ';'                        {
                                                        fprintf(stderr, "%s:%d syntax error in parcelable declaration. Expected type name, saw \"%s\".\n",
                                                                     g_currentFilename, $2.buffer.lineno, $2.buffer.data);
                                                                     ps->FileName().c_str(), $2.buffer.lineno, $2.buffer.data);
                                                        $$.user_data = NULL;
                                                    }
    ;
@@ -128,7 +140,8 @@ interface_decl:
        interface_header IDENTIFIER '{' interface_items '}' { 
                                                        interface_type* c = $1.interface_obj;
                                                        c->name = $2.buffer;
                                                        c->package = g_currentPackage ? strdup(g_currentPackage) : NULL;
                                                        c->package =
                                                        strdup(ps->Package().c_str());
                                                        c->open_brace_token = $3.buffer;
                                                        c->interface_items = $4.interface_item;
                                                        c->close_brace_token = $5.buffer;
@@ -136,12 +149,12 @@ interface_decl:
                                                    }
    |   INTERFACE error '{' interface_items '}'     {
                                                        fprintf(stderr, "%s:%d: syntax error in interface declaration.  Expected type name, saw \"%s\"\n",
                                                                    g_currentFilename, $2.buffer.lineno, $2.buffer.data);
                                                                    ps->FileName().c_str(), $2.buffer.lineno, $2.buffer.data);
                                                        $$.document_item = NULL;
                                                    }
    |   INTERFACE error '}'                {
                                                        fprintf(stderr, "%s:%d: syntax error in interface declaration.  Expected type name, saw \"%s\"\n",
                                                                    g_currentFilename, $2.buffer.lineno, $2.buffer.data);
                                                                    ps->FileName().c_str(), $2.buffer.lineno, $2.buffer.data);
                                                        $$.document_item = NULL;
                                                    }

@@ -163,7 +176,7 @@ interface_items:
                                                    }
    |   interface_items error ';'                   {
                                                        fprintf(stderr, "%s:%d: syntax error before ';' (expected method declaration)\n",
                                                                    g_currentFilename, $3.buffer.lineno);
                                                                    ps->FileName().c_str(), $3.buffer.lineno);
                                                        $$ = $1;
                                                    }
    ;
@@ -259,7 +272,8 @@ arg_list:
                                    }
                                }
    |   error                   {
                                    fprintf(stderr, "%s:%d: syntax error in parameter list\n", g_currentFilename, $1.buffer.lineno);
                                    fprintf(stderr, "%s:%d: syntax error in parameter list\n",
                                            ps->FileName().c_str(), $1.buffer.lineno);
                                    $$.arg = NULL;
                                }
    ;
@@ -279,7 +293,8 @@ arg:
type:
        IDENTIFIER              {
                                    $$.type.type = $1.buffer;
                                    init_buffer_type(&$$.type.array_token, yylineno);
                                    init_buffer_type(&$$.type.array_token,
                                      $1.buffer.lineno);
                                    $$.type.dimension = 0;
                                }
    |   IDENTIFIER ARRAY        {
@@ -289,13 +304,14 @@ type:
                                }
    |   GENERIC                 {
                                    $$.type.type = $1.buffer;
                                    init_buffer_type(&$$.type.array_token, yylineno);
                                    init_buffer_type(&$$.type.array_token,
                                      $1.buffer.lineno);
                                    $$.type.dimension = 0;
                                }
    ;

direction:
                    { init_buffer_type(&$$.buffer, yylineno); }
                    { init_buffer_type(&$$.buffer, $$.buffer.lineno); }
    |   IN          { $$.buffer = $1.buffer; }
    |   OUT         { $$.buffer = $1.buffer; }
    |   INOUT       { $$.buffer = $1.buffer; }
@@ -306,15 +322,6 @@ direction:
#include <ctype.h>
#include <stdio.h>

int g_error = 0;

int yyerror(char* errstr)
{
    fprintf(stderr, "%s:%d: %s\n", g_currentFilename, yylineno, errstr);
    g_error = 1;
    return 1;
}

void init_buffer_type(buffer_type* buf, int lineno)
{
    buf->lineno = lineno;
Loading