Exceptions in LEX&YACC - parsing

I'm developing a lex/yacc c compiler.
In order to handle failures and parse errors, I want to deploy an exception system handler.
Actually only a "parse error" message is handled whatever the problem is.for example:
typedef struct , struct_name{...} this input will produce a parsing error because of the extra comma.
My purpose is to throw a contextual exception,giving us the possibility to focus exactly where the problem is.such as for this example :
"Invalid structure declaration "
I really need help to solve this problème.

This will go into your parser. As it runs, it gets tokens from the lexer. If the next token does not "fit" the current rule, then you have a problem. Luckily, there already exists a section for dealing with these situations! See bison error recovery for the gnu version of yacc and how to deal with this. It'll go through the concepts, and variables to deal with just the situation you have here.

Related

why the assert function was disabled in dart?

import 'dart:io';
main() {
print("Enter an even number : ");
int evenNo = int.parse(stdin.readLineSync());
assert(evenNo % 2 == 0, 'wrong input');
print("You have entered : $evenNo");
}
to get this code to work properly
I had to run the dart file with '--enable-asserts' tag and before assert function was executed without passing the '--enable-asserts' tag. why was this function disabled ?
What is an assertion?
In many languages, including Dart, "assertions" specifically are meant to catch logical errors. (Dart calls these Errors.) These are errors that are due to a programming mistake. These types of errors should never happen. Conceptually, a sufficiently advanced static analyzer could prove that assertions will never fail. In practice, such analysis is difficult, so assertions are verified at runtime as a matter of practicality.
This is in contrast to runtime errors, which are unpredictable errors that occur when the program is actually running. (Dart calls these Exceptions.) Often these types of errors are due to invalid user input, but they also include file system errors and hardware failures, among other things.
Assertions are intended to be used to verify assumptions (or catch faulty ones) when debugging, and programming languages that have assertions typically allow them to be disabled for production (non-debug) code. Since assertions logically should never occur, there is no point in incurring the extra runtime cost of checking them. Since assertions can be disabled, that also should provide additional discouragement against using them improperly.
Dart chose to leave assertions disabled by default, so you must opt-in to using them with --enable-asserts. Some other languages (e.g. C) chose an opt-out system instead. I don't know the rationale for this choice for Dart, but since asserts should be used only for debugging, it makes sense to me that a language like Dart (which often might be interpreted) makes it easier for users to execute code in production mode. In contrast, for compiled languages like C, the onus of enabling or disabling assertions is placed on the developer rather than on the user.
What does this mean for your code?
Your code does not use assert properly: You use it to check runtime input. That instead should be a check that you always perform and that produces a runtime error if it fails:
if (evenNo % 2 != 0) {
throw FormatException('wrong input');
}

Solving "the lexer hack"/"typedef-name: identifier" problem in BNFC

I'm trying to parse CPP using BNFC and I've come to the "typedef-name: identifier" problem (https://en.wikipedia.org/wiki/The_lexer_hack).
This is the spec for BNFC: https://bnfc.readthedocs.io/en/latest/.
The problem comes up when a new type is defined in a program (In C using typedef) and needs to be lexed as a type for the parser to handle it correctly, but lexing stage has already occured. Other systems have hacks around this issue but I'm not sure how to solve it in BNFC.

how to get bison to bail out for all errors

I am using Flex/Bison for a script parser which needs to break out of the parser and return a nonzero status from yyparse() for ALL ERRORS. Every bit of documentation for Bison I can find is about recovery -- how can I write a rule set which bails (i.e., with YYABORT) rather than trying to recover?
Thanks for your collective wisdom.
If you refer to semantic errors, i.e., checks that you are doing in the semantic part of the syntax rules, then you can just invoke the exit() function to immediately exit the parser's executable. The parameter to exit() is the error code to return to the shell environment.
You may also implement yyerror() that would invoke exit() if you wish (to exit on syntax errors). This is documented here.
If there is no applicable error rule, bison will not attempt to recover and will immediately return when a syntax error is detected. So unless you explicitly attempt error recovery, the bison parser will act as you wish.
If you do attempt error recovery, you can still invoke YYABORT in an action to cause yyparse to return.
If your parser is not behaving in this way, please post more details.
If you want to force an error from the scanner, just return a token value which is not used in any production. That is guaranteed to create an error in the parser because the token cannot be shifted.

Flex input buffer reset after error

I'm using flex & bison to parse a custom language and I'm in the situation described here: http://www.gnu.org/software/bison/manual/html_node/How-Can-I-Reset-the-Parser.html.
To be more precise
I invoke yyparse several times, and on correct input it works
properly; but when a parse error is found, all the other calls fail
too. How can I reset the error flag of yyparse?
My parser and scanner run inside a separate thread, but there is only one thread working with the input file. In my understanding I don't need to write a reentrant scanner since there is only one thread working with the input file. In that page the problem is clearly explained but the solution is not clear to me.
It says:
Therefore, whenever you change yyin, you must tell the Lex-generated
scanner to discard its current buffer and switch to the new one. This
depends upon your implementation of Lex; see its documentation for
more. For Flex, it suffices to call ‘YY_FLUSH_BUFFER’ after each
change to yyin. If your Flex-generated scanner needs to read from
several input streams to handle features like include files, you might
consider using Flex functions like ‘yy_switch_to_buffer’ that
manipulate multiple input buffers
My parser thread calls yyparse in order to build my AST. What is not clear to me is when and where I have to call yy_flush_buffer to fix the problem. In my understanding the scanner code (generated by Flex) is called by the parser code (generated by Bison). The Bison generated code is generated by the grammar. As a result the parser code is not under my direct control. This means I cannot include the call to yy_flush_buffer into the parser code since it would be overwritten every time I generate the parser code by the grammar. It means that I should put the yy_flush_buffer in the grammr file somewhere. But where?
I fixed the problem by doing:
...
FILE *f = fopen(_filename, "r");
yyrestart(f);
yyparse();
...
I leave the question since it could be useful for other people.

Steps to follow while parsing second file through yyparse

I want to parse two files. I have Yacc/lex code which generates the parser.
It works fine when I parse the first file (a.txt) but when i parse the second file (b.txt) it returns error (syntax error), but when i parse second file(b.txt) first it can parse it smoothly.
My guess is that after reading first file when it start reading second file some buffers or states are not cleared. So i wanted to ask to know do I have to reset some buffers or states which parser maintains before proceeding for parsing second file.
I cannot paste my code over here as it is too large.
Thanks in advance.
You want a reentrant parser. Bison at least supports this, I'm not really sure if yacc does this, but switching to bison should be effectively painless.
Add %pure-parser in your grammar file.
http://www.delorie.com/gnu/docs/bison/bison_66.html
Actually I found the answer to this through some other question. The problem was in clearing the buffer so if you add a
YY_FLUSH_BUFFER
Befor opening a new file it solves the problem.

Resources