2222%glr-parser
2323%skeleton " glr2.cc"
2424%define parse.assert
25+ %define api.token.constructor
2526%header
2627%locations
2728%debug
4647 static Node
4748 stmtMerge (const Node& x0, const Node& x1);
4849
49- static int
50- yylex (yy::parser::value_type* val, yy::parser::location_type* loc );
50+ static yy::parser::symbol_type
51+ yylex ();
5152}
5253
5354%expect-rr 1
5657%printer { yyo << $$; } <Node>
5758
5859%token
59- TYPENAME " typename"
60- ID " identifier"
60+ TYPENAME " typename"
61+ ID " identifier"
62+ SEMICOLON " ;"
63+ EQUAL " ="
64+ PLUS " +"
65+ LPAREN " ("
66+ RPAREN " )"
6167
62- %right ' = '
63- %left ' + '
68+ %right " = "
69+ %left " + "
6470
6571%%
6672
6773prog : %empty
6874 | prog stmt { std::cout << @2 << " : " << $2 << ' \n ' ; }
6975 ;
7076
71- stmt : expr ' ; ' %merge <stmtMerge> { $$ = $1 ; }
77+ stmt : expr " ; " %merge <stmtMerge> { $$ = $1 ; }
7278 | decl %merge <stmtMerge>
73- | error ' ; ' { $$ = Nterm (" <error>" ); }
79+ | error " ; " { $$ = Nterm (" <error>" ); }
7480 ;
7581
7682expr : ID
77- | TYPENAME ' ( ' expr ' ) ' { $$ = Nterm (" <cast>" , $3 , $1 ); }
78- | expr ' + ' expr { $$ = Nterm (" +" , $1 , $3 ); }
79- | expr ' = ' expr { $$ = Nterm (" =" , $1 , $3 ); }
83+ | TYPENAME " ( " expr " ) " { $$ = Nterm (" <cast>" , $3 , $1 ); }
84+ | expr " + " expr { $$ = Nterm (" +" , $1 , $3 ); }
85+ | expr " = " expr { $$ = Nterm (" =" , $1 , $3 ); }
8086 ;
8187
82- decl : TYPENAME declarator ' ; '
88+ decl : TYPENAME declarator " ; "
8389 { $$ = Nterm (" <declare>" , $1 , $2 ); }
84- | TYPENAME declarator ' = ' expr ' ; '
90+ | TYPENAME declarator " = " expr " ; "
8591 { $$ = Nterm (" <init-declare>" , $1 , $2 , $4 ); }
8692 ;
8793
8894declarator
8995 : ID
90- | ' ( ' declarator ' ) ' { $$ = $2 ; }
96+ | " ( " declarator " ) " { $$ = $2 ; }
9197 ;
9298
9399%%
94100std::istream* input = nullptr ;
101+ yy::parser::location_type loc;
95102
96103// An error reporting function.
97104void
@@ -100,61 +107,63 @@ yy::parser::error (const location_type& l, const std::string& m)
100107 std::cerr << l << " : " << m << ' \n ' ;
101108}
102109
103- static int
104- yylex (yy::parser::value_type* lvalp, yy::parser::location_type* llocp )
110+ static yy::parser::symbol_type
111+ yylex ()
105112{
106- static int lineNum = 1 ;
107- static int colNum = 0 ;
108-
109113 while (true )
110114 {
115+ loc.step ();
116+ loc += 1 ;
111117 assert (!input->eof ());
112118 switch (int c = input->get ())
113119 {
114120 case EOF:
115- return 0 ;
121+ return yy::parser::make_YYEOF (loc) ;
116122 case ' \t ' :
117- colNum = (colNum + 7 ) & ~7 ;
123+ loc.end .column = (loc.end .column + 7 ) & ~7 ;
124+ loc.step ();
118125 break ;
119126 case ' ' : case ' \f ' :
120- colNum += 1 ;
127+ loc. step () ;
121128 break ;
122129 case ' \n ' :
123- lineNum += 1 ;
124- colNum = 0 ;
130+ loc.lines (1 );
131+ loc.end .column = 0 ;
132+ loc.step ();
125133 break ;
134+ case ' +' :
135+ return yy::parser::make_PLUS (loc);
136+ case ' =' :
137+ return yy::parser::make_EQUAL (loc);
138+ case ' (' :
139+ return yy::parser::make_LPAREN (loc);
140+ case ' )' :
141+ return yy::parser::make_RPAREN (loc);
142+ case ' ;' :
143+ return yy::parser::make_SEMICOLON (loc);
126144 default :
127- {
128- llocp->begin .line = llocp->end .line = lineNum;
129- llocp->begin .column = colNum;
130- int tok;
131- if (isalpha (c))
132- {
133- std::string form;
134- do
135- {
136- form += static_cast <char > (c);
137- colNum += 1 ;
138- c = input->get ();
139- }
140- while (isalnum (c) || c == ' _' );
141-
142- input->unget ();
143- tok
144- = isupper (static_cast <unsigned char > (form[0 ]))
145- ? yy::parser::token::TYPENAME
146- : yy::parser::token::ID;
147- lvalp->emplace <Node> (Term (form));
148- }
149- else
150- {
151- colNum += 1 ;
152- tok = c;
153- lvalp = nullptr ;
154- }
155- llocp->end .column = colNum;
156- return tok;
157- }
145+ if (isalpha (c))
146+ {
147+ std::string form;
148+ do
149+ {
150+ form += static_cast <char > (c);
151+ loc += 1 ;
152+ c = input->get ();
153+ }
154+ while (isalnum (c) || c == ' _' );
155+ input->unget ();
156+ loc -= 1 ;
157+ if (isupper (static_cast <unsigned char > (form[0 ])))
158+ return yy::parser::make_TYPENAME (Term (form), loc);
159+ else
160+ return yy::parser::make_ID (Term (form), loc);
161+ }
162+ else
163+ {
164+ auto msg = " invalid character: " + std::string (1 , static_cast <char > (c));
165+ throw yy::parser::syntax_error (loc, msg);
166+ }
158167 }
159168 }
160169}
@@ -173,6 +182,7 @@ process (yy::parser& parse, const std::string& file)
173182 input = &std::cin;
174183 else
175184 input = new std::ifstream (file.c_str ());
185+ loc.initialize (nullptr , 1 , 0 );
176186 int status = parse ();
177187 if (!is_stdin)
178188 delete input;
0 commit comments