I have a problem in ASN.1 compiler written in Bison.
A OCTET STRING (CONTAINING B)
The compiler Ignores CONTAINING B and refers to the data as OCTET STRING instead of referring it as B. Here is the current rule:
OctetStringType :
OCTET STRING Constraint { $$ = new OctetString($3); } |
OCTET STRING '{' NamedOctetList '}' Constraint { $$ = new OctetString($6); }
;
I tried to create a new rule:
OctetStringType :
OCTET STRING '('ContentsConstraint')' {}|
OCTET STRING Constraint { $$ = new OctetString($3); } |
OCTET STRING '{' NamedOctetList '}' Constraint { $$ = new OctetString($6); }
;
ContentsConstraint :
CONTAINING Type { }
;
When I try to print the result:
OCTET STRING '('ContentsConstraint')' {printf("$$: %s\n",$$);}
I get A. How can I access to B?Do I have to modify those rules to access B?
(I'm assuming that you are modifying an existing ASN.1 grammar, rather than one you wrote yourself.)
$$
is the semantic value being computed by the semantic action. So
OCTET STRING '('ContentsConstraint')' {printf("$$: %s\n",$$);}
makes no sense at all; you have not assigned a value to $$
, so it must be considered an undefined value.
In practice, the bison/yacc parser has effectively performed the assignment $$ = $1;
before the action has been performed (which is useful because it means that you don't have to write that when it is all you want to do in the action). So in this case, you are printing the semantic value of the first symbol in the production (which is what $1
means), which is the terminal OCTET
. However, it is unlikely that the token OCTET
has a semantic value; in most parsers, the semantic value of a keyword terminal is never used, so there is no point in assigning it.
Most bison/yacc derivatives go to some trouble to ensure that every semantic value is initialized to something in order to prevent compiler warnings (old versions didn't do this), but that something is never specified and should be treated as though it were uninitialized. In short, your code exhibits Undefined Behaviour, and could print anything.
I suppose that you want to print the semantic value of the ContentsConstraint
non-terminal. Assuming that your semantic actions for the productions which define that non-terminal all correctly assign a value for it, you can access it as $4
, since ContentsConstraint
is the fourth token in the rule. That means that you at least need to modify your rule
ContentsConstraint : CONTAINING Type { }
to
ContentsConstraint : CONTAINING Type { $$ = $2; }
since otherwise the value of ContentsConstraint
will be the result of the default action, which is $1
, which in this case does not have a semantic value, as above.
I recommend reading the bison manual, at least the first few pages up to "Semantic Actions" with reference to the examples which might make the concepts clearer. (Reading the whole manual shouldn't consume too much time and would be even more useful, but I'm aware that reading manuals is considered passé these days.)