Warning: rule useless in grammar (Bison/Yacc) - c++

I have been trying to solve this issue related to a current school assignment and would highly appreciate if anyone could explain to my why I am getting warnings from my compiler such as decafast.y:201.13-16: warning: rule useless in grammar [-Wother] | Type.
I have provided my code in the two following pastebin files:
decafast.lex: https://pastebin.com/2qzG2cwW
decafast.y: https://pastebin.com/Akg5ehW1
I have also been provided with a file 'decafast.cc' that contains classes and methods that enable me to create lists (I believe that is the purpose), found at:
https://pastebin.com/M7XRJunL
and the specification that I am supposed to follow (grammar found at bottom of page):
http://anoopsarkar.github.io/compilers-class/decafspec.html
My main concern is why I seem to be getting these warnings that are (what I assume to be) causing my code to fail. Nearly every (if not all) of my grammar is deemed to be useless, and despite my online searching (or lack thereof of understanding what has been said already), I am still unsuccessful.
I also had a secondary question if anyone is able to enlighten me. Regarding the .cc file above, I have been given a few classes that implement the decafAST class. In my parser generator file (decafast.y), I attempt to create lists by doing something along the lines of
decafStmtList *s = new decafStmtList();
I assumed that this would allow me to use the push_back() and push_front() methods, which is why I try things such as (in the case of ident_list, line 94) if I see one T_ID, then I create the list for T_ID (identifiers) and push the current T_ID into the list. If I see a situation of ident_list T_COMMA T_ID (which is what I assumed to be the case of a recurring list of comma-separated identifiers), then I would recognize that as an ident_list pattern, and thus push that T_ID into the list as well. Is this the correct way to use the lists that I have been provided?
I would like to stress that as this is an assignment question, I am pleading for any help that you can provide that will allow me to learn on my own terms. I am certain that the users on this website would easily be able to solve this assignment, therefore I would very highly appreciate any insight that you may be able to offer without giving me explicit answers. Thank you all for your time!

The grammar you were provided starts with:
Program = Externs package identifier "{" FieldDecls MethodDecls "}" .
That is, a Program consists of:
A possibly empty list of external declarations (library functions used)
The keyword "package"
An identifier
An open brace
A possibly empty list of field declarations
A possibly empty list of method declarations
A close brace.
Most of the rest of the grammar defines what field and method declarations look like, although a couple of productions define external declarations.
But your grammar is quite different: (I removed the actions because they aren't relevant to the grammar)
start: program
program: extern_list decafpackage
extern_list:
| ExternDefn
decafpackage: T_PACKAGE T_ID T_LCB T_RCB
Your decafpackage consists only of package ID { }, with nothing between the braces.
So most of the rest of the grammar productions, which detail field amd method declarations, can never be used, making them useless.
(Also, your extern_list does not define a list of ExternDecl. It defines an optional ExternDecl. I think you made that same mistake in other list productions.)

The syntax for a bison rule is:
result: components…;
As far as I see none of your rules have the semicolon.

Related

How to modify C++ code from user-input

I am currently writing a program that sits on top of a C++ interpreter. The user inputs C++ commands at runtime, which are then passed into the interpreter. For certain patterns, I want to replace the command given with a modified form, so that I can provide additional functionality.
I want to replace anything of the form
A->Draw(B1, B2)
with
MyFunc(A, B1, B2).
My first thought was regular expressions, but that would be rather error-prone, as any of A, B1, or B2 could be arbitrary C++ expressions. As these expressions could themselves contain quoted strings or parentheses, it would be quite difficult to match all cases with a regular expression. In addition, there may be multiple, nested forms of this expression
My next thought was to call clang as a subprocess, use "-dump-ast" to get the abstract syntax tree, modify that, then rebuild it into a command to be passed to the C++ interpreter. However, this would require keeping track of any environment changes, such as include files and forward declarations, in order to give clang enough information to parse the expression. As the interpreter does not expose this information, this seems infeasible as well.
The third thought was to use the C++ interpreter's own internal parsing to convert to an abstract syntax tree, then build from there. However, this interpreter does not expose the ast in any way that I was able to find.
Are there any suggestions as to how to proceed, either along one of the stated routes, or along a different route entirely?
What you want is a Program Transformation System.
These are tools that generally let you express changes to source code, written in source level patterns that essentially say:
if you see *this*, replace it by *that*
but operating on Abstract Syntax Trees so the matching and replacement process is
far more trustworthy than what you get with string hacking.
Such tools have to have parsers for the source language of interest.
The source language being C++ makes this fairly difficult.
Clang sort of qualifies; after all it can parse C++. OP objects
it cannot do so without all the environment context. To the extent
that OP is typing (well-formed) program fragments (statements, etc,.)
into the interpreter, Clang may [I don't have much experience with it
myself] have trouble getting focused on what the fragment is (statement? expression? declaration? ...). Finally, Clang isn't really a PTS; its tree modification procedures are not source-to-source transforms. That matters for convenience but might not stop OP from using it; surface syntax rewrite rule are convenient but you can always substitute procedural tree hacking with more effort. When there are more than a few rules, this starts to matter a lot.
GCC with Melt sort of qualifies in the same way that Clang does.
I'm under the impression that Melt makes GCC at best a bit less
intolerable for this kind of work. YMMV.
Our DMS Software Reengineering Toolkit with its full C++14 [EDIT July 2018: C++17] front end absolutely qualifies. DMS has been used to carry out massive transformations
on large scale C++ code bases.
DMS can parse arbitrary (well-formed) fragments of C++ without being told in advance what the syntax category is, and return an AST of the proper grammar nonterminal type, using its pattern-parsing machinery. [You may end up with multiple parses, e.g. ambiguities, that you'll have decide how to resolve, see Why can't C++ be parsed with a LR(1) parser? for more discussion] It can do this without resorting to "the environment" if you are willing to live without macro expansion while parsing, and insist the preprocessor directives (they get parsed too) are nicely structured with respect to the code fragment (#if foo{#endif not allowed) but that's unlikely a real problem for interactively entered code fragments.
DMS then offers a complete procedural AST library for manipulating the parsed trees (search, inspect, modify, build, replace) and can then regenerate surface source code from the modified tree, giving OP text
to feed to the interpreter.
Where it shines in this case is OP can likely write most of his modifications directly as source-to-source syntax rules. For his
example, he can provide DMS with a rewrite rule (untested but pretty close to right):
rule replace_Draw(A:primary,B1:expression,B2:expression):
primary->primary
"\A->Draw(\B1, \B2)" -- pattern
rewrites to
"MyFunc(\A, \B1, \B2)"; -- replacement
and DMS will take any parsed AST containing the left hand side "...Draw..." pattern and replace that subtree with the right hand side, after substituting the matches for A, B1 and B2. The quote marks are metaquotes and are used to distinguish C++ text from rule-syntax text; the backslash is a metaescape used inside metaquotes to name metavariables. For more details of what you can say in the rule syntax, see DMS Rewrite Rules.
If OP provides a set of such rules, DMS can be asked to apply the entire set.
So I think this would work just fine for OP. It is a rather heavyweight mechanism to "add" to the package he wants to provide to a 3rd party; DMS and its C++ front end are hardly "small" programs. But then modern machines have lots of resources so I think its a question of how badly does OP need to do this.
Try modify the headers to supress the method, then compiling you'll find the errors and will be able to replace all core.
As far as you have a C++ interpreter (as CERN's Root) I guess you must use the compiler to intercept all the Draw, an easy and clean way to do that is declare in the headers the Draw method as private, using some defines
class ItemWithDrawMehtod
{
....
public:
#ifdef CATCHTHEMETHOD
private:
#endif
void Draw(A,B);
#ifdef CATCHTHEMETHOD
public:
#endif
....
};
Then compile as:
gcc -DCATCHTHEMETHOD=1 yourfilein.cpp
In case, user want to input complex algorithms to the application, what I suggest is to integrate a scripting language to the app. So that the user can write code [function/algorithm in defined way] so the app can execute it in the interpreter and get the final results. Ex: Python, Perl, JS, etc.
Since you need C++ in the interpreter http://chaiscript.com/ would be a suggestion.
What happens when someone gets ahold of the Draw member function (auto draw = &A::Draw;) and then starts using draw? Presumably you'd want the same improved Draw-functionality to be called in this case too. Thus I think we can conclude that what you really want is to replace the Draw member function with a function of your own.
Since it seems you are not in a position to modify the class containing Draw directly, a solution could be to derive your own class from A and override Draw in there. Then your problem reduces to having your users use your new improved class.
You may again consider the problem of automatically translating uses of class A to your new derived class, but this still seems pretty difficult without the help of a full C++ implementation. Perhaps there is a way to hide the old definition of A and present your replacement under that name instead, via clever use of header files, but I cannot determine whether that's the case from what you've told us.
Another possibility might be to use some dynamic linker hackery using LD_PRELOAD to replace the function Draw that gets called at runtime.
There may be a way to accomplish this mostly with regular expressions.
Since anything that appears after Draw( is already formatted correctly as parameters, you don't need to fully parse them for the purpose you have outlined.
Fundamentally, the part that matters is the "SYMBOL->Draw("
SYMBOL could be any expression that resolves to an object that overloads -> or to a pointer of a type that implements Draw(...). If you reduce this to two cases, you can short-cut the parsing.
For the first case, a simple regular expression that searches for any valid C++ symbol, something similar to "[A-Za-z_][A-Za-z0-9_\.]", along with the literal expression "->Draw(". This will give you the portion that must be rewritten, since the code following this part is already formatted as valid C++ parameters.
The second case is for complex expressions that return an overloaded object or pointer. This requires a bit more effort, but a short parsing routine to walk backward through just a complex expression can be written surprisingly easily, since you don't have to support blocks (blocks in C++ cannot return objects, since lambda definitions do not call the lambda themselves, and actual nested code blocks {...} can't return anything directly inline that would apply here). Note that if the expression doesn't end in ) then it has to be a valid symbol in this context, so if you find a ) just match nested ) with ( and extract the symbol preceding the nested SYMBOL(...(...)...)->Draw() pattern. This may be possible with regular expressions, but should be fairly easy in normal code as well.
As soon as you have the symbol or expression, the replacement is trivial, going from
SYMBOL->Draw(...
to
YourFunction(SYMBOL, ...
without having to deal with the additional parameters to Draw().
As an added benefit, chained function calls are parsed for free with this model, since you can recursively iterate over the code such as
A->Draw(B...)->Draw(C...)
The first iteration identifies the first A->Draw( and rewrites the whole statement as
YourFunction(A, B...)->Draw(C...)
which then identifies the second ->Draw with an expression "YourFunction(A, ...)->" preceding it, and rewrites it as
YourFunction(YourFunction(A, B...), C...)
where B... and C... are well-formed C++ parameters, including nested calls.
Without knowing the C++ version that your interpreter supports, or the kind of code you will be rewriting, I really can't provide any sample code that is likely to be worthwhile.
One way is to load user code as a DLL, (something like plugins,)
this way, you don't need to compile your actual application, just the user code will be compiled, and you application will load it dynamically.

How to get fields and properties accessed by a method of same class?

I tried to look through the syntax tree, but the information is not sufficient enough, so I created a compilation and got the semantic model of the syntax tree. Now I can get properties and fields declarations using OfType<T> extension method where T is PropertyDeclarationSyntax or FieldDeclarationSyntax.
Inside a method.Body.Statements I thought I could look for symbols representing the ones I got from OfType<T>. But I am having a hard time figuring that part out. The syntax tree just identifies the symbol as "IdentifierName", which is not much helpful..
If this is not the correct way of looking at it, please let me know.
Use SemanticModel.GetDeclaredSymbol() on the PropertyDeclartionSyntax or the one of the VariableDeclaratorSyntax inside the FieldDefinitionSyntax. Then use SemanticModel.GetSymbolInfo() on the identifiers and see if they match. (Note that you should use ISymbol.Equals as you might not get reference equal results.

How does to!string(enum.member) works?

How does std.conv.to!string(enum.member) work? How is it possible that a function takes an enum member and returns its name? Does it use a compiler extension or something similar? It's a bit usual to me since I came from C/C++ world.
What it does is use compile time reflection on the enum type to get a list of members (the names as strings) and their values. It constructs a switch statement out of this information for a fast lookup to get the name from a value. to!SomeEnum("a_string") uses the same principle, just in the other direction.
The compile time reflection info is accessed with __traits(allMembers, TheEnumType), which returns a list of strings that can be looped over to build the switch statement. Then __traits(getMember, TheEnumType, memberName) is used to fetch the body.
Traits can be seen more of here: http://dlang.org/traits.html#allMembers
That allMembers one works on many types, not just classes as seen in the example, but also structs, enums, and more, even modules.
The phobos source code has some examples like EnumMembers in std.traits: https://github.com/D-Programming-Language/phobos/blob/master/std/traits.d#L3360
though the phobos source is kinda hard to read, but on line 3399, at the bottom of that function, you can see it using __traits(allMembers) as its data source. std.conv.to is implemented in terms of many std.traits functions.
You can also check out the sample chapter tab to get the Reflection chapter out of my D cookbook which discusses this stuff too:
http://www.packtpub.com/discover-advantages-of-programming-in-d-cookbook/book
The final example in that chapter shows how to use several of the reflection capabilities to build a little function dispatcher based on strings. The following chapter (not available for free though) shows how to build a switch out of it for better efficiency too. It's actually pretty easy: just put the case statements inside a foreach over the compile time data and the D compiler will unroll then optimize the lookup table for you!

camlp4 syntax extension, parser error

I created a syntax extension that allow the definition of a type as
type.yjson type_name {
/* type_declaration */
}
to be able to build a record value directly from a json file.
The syntax extension insert a module and the function necessary to do so.
Until here, no problem. The syntax extension do exactly what I wanted.
I start having some issue if I want to use "yjson" at some other place in my code (i.e:function parameter).
Here what I tried:
EXTEND Gram
str_item:
[
[ KEYWORD "type"; KEYWORD "."; "yjson"; tdl_raw = type_declaration ->
Here the error I get when I use "yjson" as a function parameter
[fun_binding] expected after [ipatt] (in [let_binding])
I don't really understand what happen here. It doesn't seems like the rule have been match, so why do I get a parse error ?
I do not perfectly understand the P4's mechanism around this, but [ [ "blahblah" -> ... makes blahblah as a new keyword of the language, so you can no longer use blahblah as a function argument.
To see this, try preprocess your pa_*.ml by camlp4of and see how "blahblah" is expanded to Gram.Skeyword "blahblah". It seems that this Skeyword _ is passed to Structure.using via Insert.insert of P4 and the string is registered as a new keyword.
To keep yjson usable as a normal variable, use id = LIDENT instead of "yjson" in your rule, then check id's content is "yjson" or not in your action.
If I can make a slightly off-topic remark, I think it's wrong to design a custom syntax for type-directed code generation, when there already exist two different syntaxes (one for type_conv and one for deriving), one of which (type-conv) is becoming a de facto standard.
type foo = {
...
} with json
If you pick a syntax for this, you should use this one unless you have very good reasons not to. In fact, type-conv itself is a helper utility to let you write your own type-directed code generators, so you may as well use type-conv directly for what you're trying to do.
(You probably know about Martin Jambon's Atdgen, which made a conscious choice not to use Camlp4; there is ongoing work by Alain Frisch to support annotations directly in the OCaml syntax, but that's not yet ready for consumption.)

parser with scopes and conditionals

I'm writing a C/C++/... build system (I understand this is madness ;)), and I'm having trouble designing my parser.
My "recipes" look like this:
global
{
SOURCE_DIRS src
HEADER_DIRS include
SOURCES bitwise.c \
framing.c
HEADERS \
ogg/os_types.h \
ogg/ogg.h
}
lib static ogg_static
{
NAME ogg
}
lib shared ogg_shared
{
NAME ogg
}
(This being based on the super simple libogg source tree)
# are comments, \ are "newline escapes", meaning the line continues on the next line (see QMake syntac). {} are scopes, like in C++, and global are settings that apply to every "target". This is all background, and not that relevant... I really don't know how to work with my scopes. I will need to be able to have multiple scopes, and also a form of conditional processing, in the lines of:
win32:DEFINES NO_CRT_SECURE_DEPRECATE
The parsing function will need to know on what level of scope it's at, and call itself whenever the scope is increased. There is also the problem with the location of the braces ( global { or global{ or as in the example).
How could I go about this, using Standard C++ and STL? I understand this is a whole lot of work, and that's exactly why I need a good starting point. Thanks!
What I have already is the whole ifstream and internal string/stringstream storage, so I can read word per word.
I would suggest (and this is more or less right out of the compiler textbooks) that you approach the problem in phases. This breaks things down so that the problem is much more manageable in each phase.
Focus first on the lexer phase. Your lexing phase should take the raw text and give you a sequence of tokens, such as words and special characters. The lexer phase can take care of line continuations, and handle whitespace or comments as appropriate. By handling whitespace, the lexer can simplify your parser's task: you can write the lexer so that global{, global {, and even
global
{
will all yield two tokens: one representing global and one representing {.
Also note that the lexer can tack line and column numbers onto the tokens for use later if you hit errors.
Once you've got a nice stream of tokens flowing, work on your parsing phase. The parser should take that sequence of tokens and build an abstract syntax tree, which models the syntactic structures of your document. At this point, you shouldn't be worrying about ifstream and operator>>, since the lexer should have done all that reading for you.
You've indicated an interest in calling the parsing function recursively once you see a scope. That's certainly one way to go. As you'll see, the design decision you'll have to repeatedly make is whether you literally want to call the same parse function recursively
(allowing for constructions like global { global { ... } } which you may want to disallow syntactically), or whether you want to define a slightly (or even significantly) different set of syntax rules that apply inside a scope.
Once you find yourself having to vary the rules: the key is to reuse, by refactoring into functions, as much stuff as you can reuse between the different variants of syntax. If you keep heading in this direction – using separate functions that represent the different chunks of syntax you want to deal with and having them call each other (possibly recursively) where needed – you'll ultimately end up with what we call a recursive descent parser. The Wikipedia entry has got a good simple example of one; see http://en.wikipedia.org/wiki/Recursive_descent_parser .
If you find yourself really wanting to delve deeper into the theory and practice of lexers and parsers, I do recommend you get a good solid compiler textbook to help you out. The Stack Overflow topic mentioned in the comments above will get you started: Learning to write a compiler
boost::spirit is a good recursive descent parser generator that uses C++ templates as a language extension to describe parser and lexer. It works well for native C++ compilers, but won't compile under Managed C++.
Codeproject has a tutorial article that may help.
ANTLR (use ANTLRWorks), after that you can look for FLEX/BISON and others like lemon. There are many tools out there but ANTLR and flex/bison should be enough. I personally like ANTLRWorks too much to recommend something else.
LATER: With ANTLR you can generate parser/lexer code for a variety of languages.
Unless the point of the project is specifically learning how to write a lexer and shift-reduce parser, I'd recommending using Flex and Bison, which will handle much of the parsing grunt-work for you. Writing the grammar and semantic analysis will still be a whole lot of work, don't worry ;)