Skip to content
Snippets Groups Projects
Verified Commit 24ce9ef4 authored by Recolic Keghart's avatar Recolic Keghart
Browse files

Initial commit

parents
No related branches found
No related tags found
No related merge requests found
*.cc
parser
Makefile 0 → 100644
generate: parser.tab.cc lexer.yy.cc parser.tab.h
all: parser
parser.tab.cc parser.tab.h: parser.y
@echo Generating $@...
bison --defines=parser.tab.h -o parser.tab.cc parser.y
lexer.yy.cc: lexer.l parser.tab.h
@echo Generating $@...
flex -o lexer.yy.cc lexer.l
parser: generate
g++ -o parser parser.tab.cc lexer.yy.cc
clean:
rm -f parser parser.tab.cc lexer.yy.cc parser.tab.h
lexer.l 0 → 100644
%option noyywrap
%{
#define YY_DECL int yylex()
#include "parser.tab.h"
#include <stdint.h>
#include <stdexcept>
%}
%%
[ \t\n] {}
[0-9]+ {yylval.ival = atoi(yytext); return T_INT;}
"==" {return T_EQ;}
"!=" {return T_NE;}
"&&" {return T_AND;}
"||" {return T_OR;}
">=" {return T_GE;}
"<=" {return T_LE;}
">" {return T_GT;}
"<" {return T_LT;}
[()!] {return yytext[0];}
. {throw std::runtime_error(std::string("lexer error around token: ") + yytext);}
%%
/* A Bison parser, made by GNU Bison 3.5. */
/* Bison interface for Yacc-like parsers in C
Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation,
Inc.
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 <http://www.gnu.org/licenses/>. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
under terms of your choice, so long as that work isn't itself a
parser generator using the skeleton or a modified version thereof
as a parser skeleton. Alternatively, if you modify or redistribute
the parser skeleton itself, you may (at your option) remove this
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
/* Undocumented macros, especially those whose name start with YY_,
are private implementation details. Do not rely on them. */
#ifndef YY_YY_PARSER_TAB_H_INCLUDED
# define YY_YY_PARSER_TAB_H_INCLUDED
/* Debug traces. */
#ifndef YYDEBUG
# define YYDEBUG 0
#endif
#if YYDEBUG
extern int yydebug;
#endif
/* Token type. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
enum yytokentype
{
T_INT = 258,
T_OR = 259,
T_AND = 260,
T_EQ = 261,
T_NE = 262,
T_GE = 263,
T_LE = 264,
T_GT = 265,
T_LT = 266
};
#endif
/* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
union YYSTYPE
{
#line 18 "parser.y"
int64_t ival;
#line 73 "parser.tab.h"
};
typedef union YYSTYPE YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define YYSTYPE_IS_DECLARED 1
#endif
extern YYSTYPE yylval;
int yyparse (int64_t *result);
#endif /* !YY_YY_PARSER_TAB_H_INCLUDED */
parser.y 0 → 100644
%{
#include <string>
#include <rlib/stdio.hpp>
#include <cassert>
#include <cstdlib>
extern int yylex();
extern int yyparse();
typedef struct yy_buffer_state * YY_BUFFER_STATE;
extern YY_BUFFER_STATE yy_scan_string(const char * str);
void yyerror(int64_t *result, std::string s);
static uint32_t skipped = 0;
%}
%union {
int64_t ival;
}
%token<ival> T_INT
%left T_OR
%left T_AND
%left T_EQ T_NE
%left T_GE T_LE T_GT T_LT
%right '!'
%type<ival> expr
%start entry
%parse-param {int64_t *result}
%%
entry: {*result = 0;}
| expr {*result = $1;}
;
expr: T_INT { $$ = $1; }
| expr T_AND expr { $$ = ($1 && $3); if(!$1) skipped++; }
| expr T_OR expr { $$ = ($1 || $3); if($1) skipped++; }
| expr T_EQ expr { $$ = ($1 == $3); }
| expr T_NE expr { $$ = ($1 != $3); }
| expr T_GE expr { $$ = ($1 >= $3); }
| expr T_LE expr { $$ = ($1 <= $3); }
| expr T_GT expr { $$ = ($1 > $3); }
| expr T_LT expr { $$ = ($1 < $3); }
| '(' expr ')' { $$ = $2; }
| '!' expr { $$ = ! $2; }
;
%%
#include <stdexcept>
auto parse_one(std::string expr) {
skipped = 0;
yy_scan_string(expr.c_str());
int64_t result;
assert(0 == yyparse(&result));
return std::make_pair((bool)result, skipped);
}
int main() {
rlib::print(std::boolalpha);
while(true) {
auto result = parse_one(rlib::scanln());
if(std::cin.eof()) break;
rlib::println("Output:", result.first, ',', result.second);
}
return 0;
}
void yyerror(int64_t *result, std::string msg) {
throw std::runtime_error(std::string("Parse error:") + msg);
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment