Author: kjs
Date: Thu Feb 21 11:19:57 2008
New Revision: 25941
Added:
trunk/languages/c99/src/parser/
trunk/languages/c99/src/parser/actions.pm (contents, props changed)
trunk/languages/c99/src/parser/grammar.pg (contents, props changed)
Modified:
trunk/MANIFEST
Log:
[c99]
add new action/grammar for c99.
update MANIFEST
Modified: trunk/MANIFEST
==============================================================================
--- trunk/MANIFEST (original)
+++ trunk/MANIFEST Thu Feb 21 11:19:57 2008
@@ -1,7 +1,7 @@
# ex: set ro:
# $Id$
#
-# generated by tools/dev/mk_manifest_and_skip.pl Thu Feb 21 14:47:09 2008 UT
+# generated by tools\dev\mk_manifest_and_skip.pl Thu Feb 21 19:18:22 2008 UT
#
# See tools/dev/install_files.pl for documentation on the
# format of this file.
@@ -1167,6 +1167,8 @@
languages/c99/src/CPP_PGE2AST.pir [c99]
languages/c99/src/c99.pg [c99]
languages/c99/src/c99_PGE.pir [c99]
+languages/c99/src/parser/actions.pm [c99]
+languages/c99/src/parser/grammar.pg [c99]
languages/c99/src/preamble [c99]
languages/c99/t/harness [c99]
languages/c99/t/spi.t [c99]
Added: trunk/languages/c99/src/parser/actions.pm
==============================================================================
--- (empty file)
+++ trunk/languages/c99/src/parser/actions.pm Thu Feb 21 11:19:57 2008
@@ -0,0 +1,58 @@
+# $Id$
+
+=begin comments
+
+C::Grammar::Actions - ast transformations for C
+
+This file contains the methods that are used by the parse grammar
+to build the PAST representation of an C program.
+Each method below corresponds to a rule in F<src/parser/grammar.pg>,
+and is invoked at the point where C<{*}> appears in the rule,
+with the current match object as the first argument. If the
+line containing C<{*}> also has a C<#= key> comment, then the
+value of the comment is passed as the second argument to the method.
+
+=end comments
+
+class C::Grammar::Actions;
+
+method TOP($/) {
+ my $past := PAST::Block.new( :blocktype('declaration'), :node( $/ ) );
+ for $<statement> {
+ $past.push( $( $_ ) );
+ }
+ make $past;
+}
+
+
+method statement($/) {
+ my $past := PAST::Op.new( :name('say'), :pasttype('call'), :node( $/ ) );
+ for $<value> {
+ $past.push( $( $_ ) );
+ }
+ make $past;
+}
+
+
+method value($/, $key) {
+ make $( $/{$key} );
+}
+
+
+method integer($/) {
+ make PAST::Val.new( :value( ~$/ ), :returns('Integer'), :node($/) );
+}
+
+
+method quote($/) {
+ make PAST::Val.new( :value( $($<string_literal>) ), :node($/) );
+}
+
+
+# Local Variables:
+# mode: cperl
+# cperl-indent-level: 4
+# fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4:
+
Added: trunk/languages/c99/src/parser/grammar.pg
==============================================================================
--- (empty file)
+++ trunk/languages/c99/src/parser/grammar.pg Thu Feb 21 11:19:57 2008
@@ -0,0 +1,552 @@
+# $Id$
+
+=begin overview
+
+This is the grammar for C99 written as a sequence of Perl 6 rules.
+
+
+taken from n869.pdf
+google for n869.pdf
+
+=end overview
+
+grammar C99::Grammar is PCT::Grammar;
+
+## A.2.4 External definitions
+##
+
+token TOP {
+ ^
+ <translation_unit>
+ [ $ || <.panic: Syntax error> ]
+}
+
+rule translation_unit {
+ <external_declaration>+
+}
+
+rule external_declaration {
+ | <declaration>
+ | <function_definition>
+}
+
+rule function_definition {
+ <declaration_specifiers>
+ <declarator>
+ <declaration_list>?
+ <compound_statement>
+}
+
+rule declaration_list {
+ <declaration>+
+}
+
+## A.2.2
+##
+
+rule declaration {
+ <declaration_specifiers>
+ <init_declarator_list>?
+ ';'
+}
+
+rule declaration_specifiers {
+ [ <type_specifier>
+ | <storage_class_specifier>
+ | <type_qualifier>
+ | <function_specifier>
+ ]+
+}
+
+rule function_specifier {
+ 'inline'
+}
+
+rule init_declarator_list {
+ <init_declarator> [',' <init_declarator>]*
+}
+
+rule init_declarator {
+ <declarator> ['=' <initializer>]?
+}
+
+rule storage_class_specifier {
+ | 'typedef'
+ | 'extern'
+ | 'static'
+ | 'auto'
+ | 'register'
+}
+
+rule type_specifier {
+ | 'void'
+ | 'char'
+ | 'short'
+ | 'int'
+ | 'long'
+ | 'float'
+ | 'double'
+ | 'signed'
+ | 'unsigned'
+ | '_Bool'
+ | '_Complex'
+ | '_Imaginary'
+ | <struct_or_union_specifier>
+ | <enum_specifier>
+ | <typedef_name>
+}
+
+rule struct_or_union_specifier {
+ ['struct'|'union']
+ [ <struct_or_union_definition>
+ | <pre_declaration>
+ ]
+}
+
+
+rule struct_or_union_definition {
+ <identifier>? '{' <struct_declaration>+
+ [ '}' || <.panic: '}' expected to close struct or union> ]
+}
+
+rule pre_declaration {
+ <identifier>
+}
+
+rule struct_declaration {
+ <specifier_qualifier_list> <struct_declarator>*
+ [ ';' || <.panic: ';' expected after struct declaration> ]
+}
+
+rule specifier_qualifier_list {
+ [ <type_specifier>
+ | <type_qualifier>
+ ]+
+}
+
+rule struct_declarator_list {
+ <struct_declarator> [',' <struct_declarator>]*
+}
+
+rule struct_declarator {
+ | <declarator>? ':' <constant_expression>
+ | <declarator>
+}
+
+rule enum_specifier {
+ | 'enum' <identifier>? '{' <enumerator_list> [',']? '}'
+ | 'enum' <identifier>
+}
+
+rule enumerator_list {
+ <enumerator> [',' <enumerator>]*
+}
+
+rule enumerator {
+ <enumeration_constant> ['=' <constant_expression>]?
+}
+
+rule type_qualifier {
+ | 'const'
+ | 'restrict'
+ | 'volatile'
+}
+
+rule declarator {
+ <.debug: declarator>
+ <pointer>? <direct_declarator>
+}
+
+rule direct_declarator {
+ <.debug: direct_declarator>
+ [ '(' <declarator> ')'
+ | <identifier>
+ ]
+ <declarator_suffix>*
+}
+
+rule declarator_suffix {
+ | '(' <identifier_list>? ')'
+ | '(' <parameter_type_list> ')'
+ | '[' <assignment_expression>? ']'
+ | '[' '*' ']'
+}
+
+rule pointer {
+ '*' <type_qualifier>* ['*']?
+}
+
+rule parameter_type_list {
+ <.debug: param. type list>
+ <parameter_list> [',' '...']?
+}
+
+rule parameter_list {
+ <parameter_declaration> [',' <parameter_declaration>]*
+}
+
+rule parameter_declaration {
+ <declaration_specifiers>
+ [ <declarator>
+ | <abstract_declarator>?
+ ]
+}
+
+rule identifier_list {
+ <identifier> [',' <identifier>]*
+}
+
+rule type_name {
+ <specifier_qualifier_list> <abstract_declarator>?
+}
+
+rule abstract_declarator {
+ | '*'
+ | ['*']? <direct_abstract_declarator>
+}
+
+rule direct_abstract_declarator {
+ [
+ | '(' <abstract_declatator> ')'
+ | '[' <assignment_expression>? ']'
+ | '(' <parameter_type_list> ')'
+ ]
+ <direct_abstract_declarator_1>*
+}
+
+rule direct_abstract_declarator_1 {
+ | '[' <assignment_expression>? ']'
+ | '[' '*' ']'
+ | '(' <parameter_type_list> ')'
+}
+
+rule typedef_name {
+
+## a typedef name can be a return type specifier. This is ambiguous, because
+## the parser doesn't know if it's a return type thingie or the name of the
+## function. Therefore, typedef'd names must be stored in a %hash, so that
+## this rule is not calling <identifier>, but inspecting the registered
+## typedef'd names. For now, specify 'foo' as the only typedef'd name.
+##
+ #<identifier>
+ 'foo'
+}
+
+rule initializer {
+ | <assignment_expression>
+ | '{' <initializer_list> [',']? '}'
+}
+
+rule initializer_list {
+ <initializer_item> [',' <initializer_item>]*
+}
+
+rule initializer_item {
+ <designation>? <initializer>
+}
+
+rule designation {
+ <designator>+ '='
+}
+
+rule designator {
+ | '[' <constant_expression> ']'
+ | '.' <identifier>
+}
+
+
+## A.2.3 Statements
+##
+
+rule statement {
+ | <labeled_statement>
+ | <compound_statement>
+ | <expression_statement>
+ | <selection_statement>
+ | <iteration_statement>
+ | <jump_statement>
+}
+
+rule labeled_statement {
+ | <identifier> ':' <statement>
+ | 'case' <constant_expression> ':' <statement>
+ | 'default' ':' <statement>
+}
+
+rule compound_statement {
+ '{' <block_item>* '}'
+}
+
+rule block_item {
+ | <declaration>
+ | <statement>
+}
+
+rule expression_statement {
+ <expression>? ';'
+}
+
+rule selection_statement {
+ | 'if' '(' <expression> ')' <statement> ['else' <statement>]?
+ | 'switch' '(' <expression> ')' <statement>
+}
+
+rule iteration_statement {
+ | 'while' '(' <expression> ')' <statement>
+ | 'do' <statement> 'while' '(' <expression> ')' ';'
+ | 'for' '(' <expression>? ';' <expression>? ';' <expression>? ')'
<statement>
+ | 'for' '(' <declaration> <expression>? ';' <expression>? ')' <statement>
+}
+
+rule jump_statement {
+ | 'goto' <identifier> ';'
+ | 'continue' ';'
+ | 'break' ';'
+ | 'return' <expression>? ';'
+}
+
+
+## A.1.1 Lexical elements
+##
+##rule token {
+## | <keyword>
+## | <identifier>
+## | <constant>
+## | <c_string_literal>
+## | <punctuator>
+##}
+
+regex preprocessing_token {
+ | <header_name>
+ | <identifier>
+ | <pp_number>
+ | <character_constant>
+ | <string_literal>
+ | <!pound> <punctuator>
+ | <universal_character_name>
+ | <-[# \r\n\t]>\S* ## <-[#]-\S>\S* ##non-whitespace
+}
+
+## A.1.2 Keywords
+##
+token keyword {
+ [ auto | enum | restrict | unsigned
+ | break | extern | return | void
+ | case | float | short | volatile
+ | char | for | signed | while
+ | const | goto | sizeof | _Bool
+ | continue | if | static | _Complex
+ | default | inline | struct | _Imaginary
+ | do | int | switch
+ | double | long | typedef
+ | else | register | union ]>>
+
+}
+
+token reserved_word {
+ <keyword>
+}
+
+
+token identifier {
+ <!reserved_word> <alpha>+
+}
+
+#
+# <identifier_nondigit> [ <identifier_nondigit> | <digit> ]*
+#}
+
+token identifier_nondigit {
+ <alpha> | <[_]> | <universal_character_name>
+}
+
+## A.1.4 Universal character names
+##
+token universal_character_name {
+ | '\u' <xdigit>**{4}
+ | '\U' <xdigit>**{8}
+}
+
+
+## A.1.5 Constants
+##
+token constant {
+ | <integer_constant>
+ | <floating_constant>
+ | <enumeration_constant>
+ | <character_constant>
+}
+
+token integer_constant {
+ [ <decimal_constant>
+ | <octal_constant>
+ | <hexadecimal_constant>
+ ] <integer_suffix>?
+}
+
+token decimal_constant {
+ <[1..9]> <digit>*
+}
+
+token octal_constant {
+ 0 <[0..7]>*
+}
+
+token hexadecimal_constant {
+ 0 <[xX]> <xdigit>+
+}
+
+token integer_suffix {
+ | <[uU]> [ll?|LL?]?
+ | [ll?|LL?] <[uU]>?
+}
+
+token floating_constant {
+ | <decimal_floating_constant>
+ | <hexadecimal_floating_constant>
+}
+
+token decimal_floating_constant {
+ [ <fractional_constant> <exponent_part>?
+ | <digit_sequence> <exponent_part>
+ ] <floating_suffix>?
+}
+
+token hexadecimal_prefix {
+ 0 <[xX]>
+}
+
+token hexadecimal_floating_constant {
+ <hexadecimal_prefix>
+ [ <hexadecimal_fractional_constant>
+ | <hexadecimal_digit_constant>
+ ] <binary_exponent_part> <floating_suffix>?
+}
+
+token fractional_constant {
+ | <digit_sequence>? \. <digit_sequence>
+ | <digit_sequence> \.
+}
+
+token exponent_part {
+ <[eE]> ['+'|'-']? <digit_sequence>
+}
+
+token digit_sequence { <digit>+ }
+
+token hexadecimal_fractional_constant {
+ | <hexadecimal_digit_sequence>? \. <hexadecimal_digit_sequence>
+ | <hexadecimal_digit_sequence> \.
+}
+
+token binary_exponent_part {
+ <[pP]> ['+'|'-']? <digit_sequence>
+}
+
+token hexadecimal_digit_sequence { <xdigit>+ }
+
+token floating_suffix { <[fFlL]> }
+
+token enumeration_constant { <identifier> }
+
+token character_constant { [L]? \' <c_char>+ \' }
+
+token <c_char> { <-['\\\n]> | <escape_sequence> }
+
+token escape_sequence {
+ \\
+ [ <['"?\\abfnrtv]>
+ | <octal_digit>**{1..3}
+ | x <xdigit>+
+ | <universal_character_name>
+ ]
+}
+
+## A.1.6 String literals
+token c_string_literal { [L]? \" <s_char>* \" }
+
+token s_char { <-["\\\n]> | <escape_sequence> }
+
+
+## A.2 Phrase structure grammar
+##
+
+## A.2.1 Expressions
+##
+
+rule constant_expression {
+ <conditional_expression>
+}
+
+rule expression {
+ <assignment_expression> [',' <assignment_expression>]*
+}
+
+rule assignment_expression {
+ [<unary_expression> <assign_op>]* <conditional_expression>
+}
+
+rule assign_op { '='|'*='|'/='|'%='|'+='|'-='|'<<='|'>>='|'&='|'^='|'|=' }
+
+rule conditional_expression {
+ <logical_expression> ['?' <expression> ':' <conditional_expression>]?
+}
+
+rule logical_expression is optable { ... }
+
+proto 'infix:||' is precedence('1') { ... }
+
+proto 'term:' is parsed(&cast_expression) { ... }
+
+
+rule postfix_expression {
+ <primary_expression>
+}
+
+rule unary_expression {
+ <postfix_expression>
+}
+
+rule cast_expression {
+ ['(' <type_name> ')']* <unary_expression>
+}
+
+rule primary_expression {
+ | <identifier>
+ | <constant>
+ | <c_string_literal>
+ | '(' <expression> ')'
+}
+
+token ws {
+ [
+ | '//' \N* \n
+ | '/*' .*? '*/'
+ | \s+
+ ]*
+}
+
+## copied from old c99 grammar.
+##
+## A.1.7 Punctuators
+##token punctuator {
+## | \[ | \] | <[(){}.]> | <'->'>
+## | <'++'> | <'--'> | <[&*+\-~!/%]>
+## | <'<<'> | <'>>'> | <[<>]>
+## | <'<='> | <'>='> | <'=='> | <'!='>
+## | <[^|]> | <'&&'> | <'||'>
+## | <[?:;]> | <'...'>
+## | [ <[*/%+\-&^|]> | <'<<'> | <'>>'> ] <'='>
+## | <[,#]> | <'##'>
+## | <'<:'> | <':>'> | <'<%'> | <'%>'> | <'%:'> | <'%:%:'>
+##}
+##
+#### A.1.8 Header names
+##token header_name {
+## | \< $<name:>=<?h_char>+ \>
+## | " $<name>:=<?q_char>+ "
+##}
+##
+##token h_char { <-[\n>]> }
+##token q_char { <-[\n"]> }
+##
\ No newline at end of file