Permalink
Browse files

Refactor grammars into one grammar.

  • Loading branch information...
1 parent 4e2e24c commit 83472bace6f65ba33790aaf59d3b3ec942baf756 @ingydotnet committed Jul 26, 2010
Showing with 38 additions and 52 deletions.
  1. +18 −20 lib/TestML/Parser.pm
  2. +16 −32 lib/TestML/Parser/Grammar.pm
  3. +4 −0 notes/todo
View
@@ -7,28 +7,21 @@ use TestML::Document;
class TestML::Parser;
-my $doc;
+my $document;
my $data;
my $statement;
my $transform_arguments;
my @expression_stack;
method parse($testml) {
- $doc = TestML::Document.new();
+ $document = TestML::Document.new();
@expression_stack = ();
- my $rc1 = TestML::Parser::Grammar.parse($testml, :actions(TestML::Parser::Actions));
- if (not $rc1) {
- die "Parse TestML failed";
- }
- $TestML::Parser::Grammar::DataSection::block_marker = $doc.meta.data<BlockMarker>;
- $TestML::Parser::Grammar::DataSection::point_marker = $doc.meta.data<PointMarker>;
- my $rc2 = TestML::Parser::Grammar::DataSection.parse(
- $data, :actions(TestML::Parser::Actions)
- );
- if (not $rc2) {
- die "Parse TestML Data failed";
- }
- return $doc;
+ TestML::Parser::Grammar.parse(
+ $testml,
+ :rule('document'),
+ :actions(TestML::Parser::Actions),
+ ) or die "Parse TestML failed";
+ return $document;
}
method parse_data ($parser) {
@@ -50,7 +43,6 @@ method parse_data ($parser) {
class TestML::Parser::Actions;
### Base Section ###
-
method quoted_string($/) {
make ~$/.substr(1, -1);
}
@@ -79,12 +71,17 @@ method sq_escape($/) {
### Meta Section ###
+method meta_section($/) {
+ $TestML::Parser::Grammar::block_marker = $document.meta.data<BlockMarker>;
+ $TestML::Parser::Grammar::point_marker = $document.meta.data<PointMarker>;
+}
+
method meta_testml_statement($/) {
- $doc.meta.data<TestML> = ~$<testml_version>;
+ $document.meta.data<TestML> = ~$<testml_version>;
}
method meta_statement($/) {
- $doc.meta.data{~$<meta_keyword>} = $<meta_value>.ast;
+ $document.meta.data{~$<meta_keyword>} = $<meta_value>.ast;
}
method meta_value($/) {
@@ -101,7 +98,7 @@ method test_statement_start($/) {
}
method test_statement($/) {
- $doc.test.statements.push($statement);
+ $document.test.statements.push($statement);
@expression_stack.pop();
}
@@ -150,6 +147,7 @@ method assertion_operator($/) {
@expression_stack.push($statement.assertion.expression);
}
+
### Data Section ###
method data_section($/) {
$data = ~$/;
@@ -170,7 +168,7 @@ method data_block($/) {
}
$block.points{$name} = $value;
}
- $doc.data.blocks.push($block);
+ $document.data.blocks.push($block);
}
method SEMICOLON_ERROR($/) {
@@ -1,32 +1,28 @@
use v6;
-grammar TestML::Parser::Grammar::Base;
+
+grammar TestML::Parser::Grammar;
+
+our $block_marker = '===';
+our $point_marker = '---';
regex ALWAYS { <?> } # Always match
regex ANY { . } # Any unicode character
regex SPACE { <blank> } # A space or tab character
-regex BREAK { \n } # A newline character
regex EOL { \r? \n } # A Unix or DOS line ending
regex NON_BREAK { \N } # Any character except newline
-regex NON_SPACE_BREAK
- { <![\ \n]> } # Any character except space or newline
regex LOWER { <[a..z]> } # Lower case ASCII alphabetic character
regex UPPER { <[A..Z]> } # Upper case ASCII alphabetic character
-regex ALPHANUM { <[A..Za..z0..9]> } # ASCII alphanumeric character
regex WORD { <[A..Za..z0..9_]> } # A "word" character
regex DIGIT { <[0..9]> } # A numeric digit
regex STAR { '*' } # An asterisk
regex DOT { '.' } # A period character
regex SEMI { ';' } # A semicolon
regex HASH { '#' } # An octothorpe (or hash) character
-regex BACK { '\\' } # A backslash character
-regex SINGLE { "'" } # A single quote character
-regex DOUBLE { '"' } # A double quote character
-regex ESCAPE { <[0nt]> } # One of the escapable character IDs
-token line { <NON_BREAK>* <EOL> }
+token line { <NON_BREAK>* <EOL> }
token blank_line { <SPACE>* <EOL> }
-token comment { <HASH> <line> }
-token wspace { <SPACE> | <EOL> | <comment> }
+token comment { <HASH> <line> }
+token wspace { <SPACE> | <EOL> | <comment> }
token unquoted_string {
[
@@ -78,15 +74,12 @@ token dq_escape { <["\\nrt]> }
#------------------------------------------------------------------------------#
-grammar TestML::Parser::Grammar is TestML::Parser::Grammar::Base;
-
-rule TOP {^ <document> $}
-
-rule document {
+# This is the TOP rule:
+rule document {^
<meta_section>
<test_section>
<data_section>?
-}
+$}
#------------------------------------------------------------------------------#
rule meta_section {
@@ -228,22 +221,8 @@ token assertion_function_name {
'EQ'
}
-token data_section {
- <ANY>*
-}
-
-token SEMICOLON_ERROR { <ALWAYS> }
-token NO_META_TESTML_ERROR { <ALWAYS> }
-
#------------------------------------------------------------------------------#
-grammar TestML::Parser::Grammar::DataSection is TestML::Parser::Grammar::Base;
-
-our $block_marker = '===';
-our $point_marker = '---';
-
-token TOP { ^ <data_section> $ }
-
token data_section {
<data_block>*
}
@@ -298,3 +277,8 @@ token core_point_name {
token user_point_name {
<LOWER> <WORD>*
}
+
+
+#------------------------------------------------------------------------------#
+token SEMICOLON_ERROR { <ALWAYS> }
+token NO_META_TESTML_ERROR { <ALWAYS> }
View
@@ -1,3 +1,7 @@
++ Remove TOP rules.
++ Combine grammars into one.
++ Parse the Inline data in one go.
+
- Make == (EQ) an assertion function:
$left.EQ($right);
- Add .HAS .OK .NOK etc.

0 comments on commit 83472ba

Please sign in to comment.