summaryrefslogtreecommitdiff
path: root/source4/build/pasn1/asn1.yp
diff options
context:
space:
mode:
Diffstat (limited to 'source4/build/pasn1/asn1.yp')
-rw-r--r--source4/build/pasn1/asn1.yp271
1 files changed, 271 insertions, 0 deletions
diff --git a/source4/build/pasn1/asn1.yp b/source4/build/pasn1/asn1.yp
new file mode 100644
index 0000000000..5fa6460d7e
--- /dev/null
+++ b/source4/build/pasn1/asn1.yp
@@ -0,0 +1,271 @@
+########################
+# ASN.1 Parse::Yapp parser
+# Copyright (C) Stefan (metze) Metzmacher <metze@samba.org>
+# released under the GNU GPL version 2 or later
+
+
+
+# the precedence actually doesn't matter at all for this grammer, but
+# by providing a precedence we reduce the number of conflicts
+# enormously
+%left '-' '+' '&' '|' '*' '>' '.' '/' '(' ')' '[' ']' ':' ',' ';'
+
+
+################
+# grammer
+%%
+
+asn1:
+ asn1_def
+ { [ $_[1] ] }
+ | asn1 asn1_def
+ { push(@{$_[1]}, $_[2]); $_[1] }
+;
+
+asn1_def:
+ asn1_target asn1_delim asn1_application asn1_type
+ {{
+ "OBJECT" => "ASN1_DEF",
+ "IDENTIFIER" => $_[1],
+ "APPLICATION" => $_[3],
+ "STRUCTURE" => $_[4]
+ }}
+;
+
+asn1_target:
+ identifier
+;
+
+asn1_delim:
+ ':' ':' '='
+;
+
+asn1_application:
+ #empty
+ | '[' 'APPLICATION' constant ']'
+ { $_[3] }
+;
+
+asn1_type:
+ asn1_boolean
+ | asn1_integer
+ | asn1_bit_string
+ | asn1_octet_string
+ | asn1_null
+ | asn1_object_identifier
+ | asn1_real
+ | asn1_enumerated
+ | asn1_sequence
+;
+
+asn1_boolean:
+ 'BOOLEAN'
+ {{
+ "TYPE" => "BOOLEAN",
+ "TAG" => 1
+ }}
+;
+
+asn1_integer:
+ 'INTEGER'
+ {{
+ "TYPE" => "INTEGER",
+ "TAG" => 2
+ }}
+ | 'INTEGER' '(' constant '.' '.' constant ')'
+ {{
+ "TYPE" => "INTEGER",
+ "TAG" => 2,
+ "RANGE_LOW" => $_[3],
+ "RENAGE_HIGH" => $_[6]
+ }}
+;
+
+asn1_bit_string:
+ 'BIT' 'STRING'
+ {{
+ "TYPE" => "BIT STRING",
+ "TAG" => 3
+ }}
+;
+
+asn1_octet_string:
+ 'OCTET' 'STRING'
+ {{
+ "TYPE" => "OCTET STRING",
+ "TAG" => 4
+ }}
+;
+
+asn1_null:
+ 'NULL'
+ {{
+ "TYPE" => "NULL",
+ "TAG" => 5
+ }}
+;
+
+asn1_object_identifier:
+ 'OBJECT' 'IDENTIFIER'
+ {{
+ "TYPE" => "OBJECT IDENTIFIER",
+ "TAG" => 6
+ }}
+;
+
+asn1_real:
+ 'REAL'
+ {{
+ "TYPE" => "REAL",
+ "TAG" => 9
+ }}
+;
+
+asn1_enumerated:
+ 'ENUMERATED'
+ {{
+ "TYPE" => "ENUMERATED",
+ "TAG" => 10
+ }}
+;
+
+asn1_sequence:
+ 'SEQUENCE' '{' asn1_var_dec_list '}'
+ {{
+ "TYPE" => "SEQUENCE",
+ "TAG" => 16,
+ "STRUCTURE" => $_[3]
+ }}
+;
+
+asn1_var_dec_list:
+ asn1_var_dec
+ { [ $_[1] ] }
+ | asn1_var_dec_list ',' asn1_var_dec
+ { push(@{$_[1]}, $_[3]); $_[1] }
+;
+
+asn1_var_dec:
+ identifier asn1_type
+ {{
+ "NAME" => $_[1],
+ "TYPE" => $_[2]
+ }}
+;
+
+anytext: #empty { "" }
+ | identifier | constant | text
+ | anytext '-' anytext { "$_[1]$_[2]$_[3]" }
+ | anytext '.' anytext { "$_[1]$_[2]$_[3]" }
+ | anytext '*' anytext { "$_[1]$_[2]$_[3]" }
+ | anytext '>' anytext { "$_[1]$_[2]$_[3]" }
+ | anytext '|' anytext { "$_[1]$_[2]$_[3]" }
+ | anytext '&' anytext { "$_[1]$_[2]$_[3]" }
+ | anytext '/' anytext { "$_[1]$_[2]$_[3]" }
+ | anytext '+' anytext { "$_[1]$_[2]$_[3]" }
+ | anytext '(' anytext ')' anytext { "$_[1]$_[2]$_[3]$_[4]$_[5]" }
+;
+
+identifier: IDENTIFIER
+;
+
+constant: CONSTANT
+;
+
+text: TEXT { "\"$_[1]\"" }
+;
+
+#####################################
+# start code
+%%
+
+use util;
+
+sub _ASN1_Error {
+ if (exists $_[0]->YYData->{ERRMSG}) {
+ print $_[0]->YYData->{ERRMSG};
+ delete $_[0]->YYData->{ERRMSG};
+ return;
+ };
+ my $line = $_[0]->YYData->{LINE};
+ my $last_token = $_[0]->YYData->{LAST_TOKEN};
+ my $file = $_[0]->YYData->{INPUT_FILENAME};
+
+ print "$file:$line: Syntax error near '$last_token'\n";
+}
+
+sub _ASN1_Lexer($)
+{
+ my($parser)=shift;
+
+ $parser->YYData->{INPUT}
+ or return('',undef);
+
+again:
+ $parser->YYData->{INPUT} =~ s/^[ \t]*//;
+
+ for ($parser->YYData->{INPUT}) {
+ if (/^\#/) {
+ if (s/^\# (\d+) \"(.*?)\"( \d+|)//) {
+ $parser->YYData->{LINE} = $1-1;
+ $parser->YYData->{INPUT_FILENAME} = $2;
+ goto again;
+ }
+ if (s/^\#line (\d+) \"(.*?)\"( \d+|)//) {
+ $parser->YYData->{LINE} = $1-1;
+ $parser->YYData->{INPUT_FILENAME} = $2;
+ goto again;
+ }
+ if (s/^(\#.*)$//m) {
+ goto again;
+ }
+ }
+ if (s/^(\n)//) {
+ $parser->YYData->{LINE}++;
+ goto again;
+ }
+ if (s/^\"(.*?)\"//) {
+ $parser->YYData->{LAST_TOKEN} = $1;
+ return('TEXT',$1);
+ }
+ if (s/^(\d+)(\W|$)/$2/) {
+ $parser->YYData->{LAST_TOKEN} = $1;
+ return('CONSTANT',$1);
+ }
+ if (s/^([\w_]+)//) {
+ $parser->YYData->{LAST_TOKEN} = $1;
+ if ($1 =~
+ /^(SEQUENCE|INTEGER|OCTET|STRING|
+ APPLICATION|OPTIONAL|NULL|COMPONENTS|OF|
+ BOOLEAN|ENUMERATED|CHOISE|REAL|BIT|OBJECT|IDENTIFIER
+ DEFAULT|FALSE|TRUE|SET)$/x) {
+ return $1;
+ }
+ return('IDENTIFIER',$1);
+ }
+ if (s/^(.)//s) {
+ $parser->YYData->{LAST_TOKEN} = $1;
+ return($1,$1);
+ }
+ }
+}
+
+sub parse_asn1($$)
+{
+ my $self = shift;
+ my $filename = shift;
+
+ my $saved_delim = $/;
+ undef $/;
+ my $cpp = $ENV{CPP};
+ if (! defined $cpp) {
+ $cpp = "cpp"
+ }
+ my $data = `$cpp -xc $filename`;
+ $/ = $saved_delim;
+
+ $self->YYData->{INPUT} = $data;
+ $self->YYData->{LINE} = 0;
+ $self->YYData->{LAST_TOKEN} = "NONE";
+ return $self->YYParse( yylex => \&_ASN1_Lexer, yyerror => \&_ASN1_Error );
+}