diff options
author | Akim Demaille <akim.demaille@gmail.com> | 2021-01-10 16:37:47 +0100 |
---|---|---|
committer | Akim Demaille <akim.demaille@gmail.com> | 2021-01-10 17:12:50 +0100 |
commit | 6833b1be476ea67e7a452028b071028c79d822d5 (patch) | |
tree | 3a27685d44910fd4a16bec59f5e01233bd80ad58 /examples | |
parent | 4aa731d110111ae658ea632322e46c1a3f475946 (diff) | |
download | bison-6833b1be476ea67e7a452028b071028c79d822d5.tar.gz |
glr2.cc: add support for api.token.constructor
* data/skeletons/glr2.cc: Add support for api.token.constructor.
* examples/c++/glr/c++-types.yy: Use it.
* examples/c++/glr/c++-types.test: Adjust expectations for error
messages.
Diffstat (limited to 'examples')
-rw-r--r-- | examples/c++/glr/c++-types.test | 2 | ||||
-rw-r--r-- | examples/c++/glr/c++-types.yy | 120 |
2 files changed, 66 insertions, 56 deletions
diff --git a/examples/c++/glr/c++-types.test b/examples/c++/glr/c++-types.test index 6a00cd8c..9a3f7506 100644 --- a/examples/c++/glr/c++-types.test +++ b/examples/c++/glr/c++-types.test @@ -47,4 +47,4 @@ run 0 "\ 5.0-13: <OR>(<init-declare>(T, y, +(z, q)), =(<cast>(y, T), +(z, q))) 7.0-15: <error> 9.0-5: +(z, q) -err: 7.5: syntax error, unexpected identifier, expecting '=' or '+' or ')'" +err: 7.5: syntax error, unexpected identifier, expecting = or + or )" diff --git a/examples/c++/glr/c++-types.yy b/examples/c++/glr/c++-types.yy index 594b356e..c4012a00 100644 --- a/examples/c++/glr/c++-types.yy +++ b/examples/c++/glr/c++-types.yy @@ -22,6 +22,7 @@ %glr-parser %skeleton "glr2.cc" %define parse.assert +%define api.token.constructor %header %locations %debug @@ -46,8 +47,8 @@ static Node stmtMerge (const Node& x0, const Node& x1); - static int - yylex (yy::parser::value_type* val, yy::parser::location_type* loc); + static yy::parser::symbol_type + yylex (); } %expect-rr 1 @@ -56,11 +57,16 @@ %printer { yyo << $$; } <Node> %token - TYPENAME "typename" - ID "identifier" + TYPENAME "typename" + ID "identifier" + SEMICOLON ";" + EQUAL "=" + PLUS "+" + LPAREN "(" + RPAREN ")" -%right '=' -%left '+' +%right "=" +%left "+" %% @@ -68,30 +74,31 @@ prog : %empty | prog stmt { std::cout << @2 << ": " << $2 << '\n'; } ; -stmt : expr ';' %merge <stmtMerge> { $$ = $1; } +stmt : expr ";" %merge <stmtMerge> { $$ = $1; } | decl %merge <stmtMerge> - | error ';' { $$ = Nterm ("<error>"); } + | error ";" { $$ = Nterm ("<error>"); } ; expr : ID - | TYPENAME '(' expr ')' { $$ = Nterm ("<cast>", $3, $1); } - | expr '+' expr { $$ = Nterm ("+", $1, $3); } - | expr '=' expr { $$ = Nterm ("=", $1, $3); } + | TYPENAME "(" expr ")" { $$ = Nterm ("<cast>", $3, $1); } + | expr "+" expr { $$ = Nterm ("+", $1, $3); } + | expr "=" expr { $$ = Nterm ("=", $1, $3); } ; -decl : TYPENAME declarator ';' +decl : TYPENAME declarator ";" { $$ = Nterm ("<declare>", $1, $2); } - | TYPENAME declarator '=' expr ';' + | TYPENAME declarator "=" expr ";" { $$ = Nterm ("<init-declare>", $1, $2, $4); } ; declarator : ID - | '(' declarator ')' { $$ = $2; } + | "(" declarator ")" { $$ = $2; } ; %% std::istream* input = nullptr; +yy::parser::location_type loc; // An error reporting function. void @@ -100,61 +107,63 @@ yy::parser::error (const location_type& l, const std::string& m) std::cerr << l << ": " << m << '\n'; } -static int -yylex (yy::parser::value_type* lvalp, yy::parser::location_type* llocp) +static yy::parser::symbol_type +yylex () { - static int lineNum = 1; - static int colNum = 0; - while (true) { + loc.step (); + loc += 1; assert (!input->eof ()); switch (int c = input->get ()) { case EOF: - return 0; + return yy::parser::make_YYEOF (loc); case '\t': - colNum = (colNum + 7) & ~7; + loc.end.column = (loc.end.column + 7) & ~7; + loc.step (); break; case ' ': case '\f': - colNum += 1; + loc.step (); break; case '\n': - lineNum += 1; - colNum = 0; + loc.lines (1); + loc.end.column = 0; + loc.step (); break; + case '+': + return yy::parser::make_PLUS (loc); + case '=': + return yy::parser::make_EQUAL (loc); + case '(': + return yy::parser::make_LPAREN (loc); + case ')': + return yy::parser::make_RPAREN (loc); + case ';': + return yy::parser::make_SEMICOLON (loc); default: - { - llocp->begin.line = llocp->end.line = lineNum; - llocp->begin.column = colNum; - int tok; - if (isalpha (c)) - { - std::string form; - do - { - form += static_cast<char> (c); - colNum += 1; - c = input->get (); - } - while (isalnum (c) || c == '_'); - - input->unget (); - tok - = isupper (static_cast <unsigned char> (form[0])) - ? yy::parser::token::TYPENAME - : yy::parser::token::ID; - lvalp->emplace<Node> (Term (form)); - } - else - { - colNum += 1; - tok = c; - lvalp = nullptr; - } - llocp->end.column = colNum; - return tok; - } + if (isalpha (c)) + { + std::string form; + do + { + form += static_cast<char> (c); + loc += 1; + c = input->get (); + } + while (isalnum (c) || c == '_'); + input->unget (); + loc -= 1; + if (isupper (static_cast <unsigned char> (form[0]))) + return yy::parser::make_TYPENAME (Term (form), loc); + else + return yy::parser::make_ID (Term (form), loc); + } + else + { + auto msg = "invalid character: " + std::string(1, static_cast<char> (c)); + throw yy::parser::syntax_error (loc, msg); + } } } } @@ -173,6 +182,7 @@ process (yy::parser& parse, const std::string& file) input = &std::cin; else input = new std::ifstream (file.c_str ()); + loc.initialize (nullptr, 1, 0); int status = parse (); if (!is_stdin) delete input; |