8 Commits
23 changed files with 494 additions and 327 deletions

No files matched your search

+16
View File
@@ -1,3 +1,19 @@
## v2.0.0
### Improvements
- Log conflicting rules on reduce/reduce conflict (#31)
- Use 1-based row and column values for position values (#30)
### Fixes
- Fix named optional rules (#29)
### Upgrading
- Adjust all uses of p_position_t row and col values to expect 1-based instead
of 0-based values.
## v1.5.1 ## v1.5.1
### Improvements ### Improvements
+20 -18
View File
@@ -1,34 +1,36 @@
GEM GEM
remote: https://rubygems.org/ remote: https://rubygems.org/
specs: specs:
diff-lcs (1.5.0) date (3.4.1)
docile (1.4.0) diff-lcs (1.5.1)
psych (5.1.0) docile (1.4.1)
psych (5.2.2)
date
stringio stringio
rake (13.0.6) rake (13.2.1)
rdoc (6.5.0) rdoc (6.10.0)
psych (>= 4.0.0) psych (>= 4.0.0)
redcarpet (3.6.0) redcarpet (3.6.0)
rspec (3.12.0) rspec (3.13.0)
rspec-core (~> 3.12.0) rspec-core (~> 3.13.0)
rspec-expectations (~> 3.12.0) rspec-expectations (~> 3.13.0)
rspec-mocks (~> 3.12.0) rspec-mocks (~> 3.13.0)
rspec-core (3.12.2) rspec-core (3.13.2)
rspec-support (~> 3.12.0) rspec-support (~> 3.13.0)
rspec-expectations (3.12.3) rspec-expectations (3.13.3)
diff-lcs (>= 1.2.0, < 2.0) diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.12.0) rspec-support (~> 3.13.0)
rspec-mocks (3.12.6) rspec-mocks (3.13.2)
diff-lcs (>= 1.2.0, < 2.0) diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.12.0) rspec-support (~> 3.13.0)
rspec-support (3.12.1) rspec-support (3.13.2)
simplecov (0.22.0) simplecov (0.22.0)
docile (~> 1.1) docile (~> 1.1)
simplecov-html (~> 0.11) simplecov-html (~> 0.11)
simplecov_json_formatter (~> 0.1) simplecov_json_formatter (~> 0.1)
simplecov-html (0.12.3) simplecov-html (0.13.1)
simplecov_json_formatter (0.1.4) simplecov_json_formatter (0.1.4)
stringio (3.0.7) stringio (3.1.2)
syntax (1.2.2) syntax (1.2.2)
PLATFORMS PLATFORMS
+4 -2
View File
@@ -60,6 +60,8 @@ void <%= @grammar.prefix %>context_init(<%= @grammar.prefix %>context_t * contex
/* Lexer initialization. */ /* Lexer initialization. */
newcontext.input = input; newcontext.input = input;
newcontext.input_length = input_length; newcontext.input_length = input_length;
newcontext.text_position.row = 1u;
newcontext.text_position.col = 1u;
newcontext.mode = <%= @lexer.mode_id("default") %>; newcontext.mode = <%= @lexer.mode_id("default") %>;
/* Copy to the user's context structure. */ /* Copy to the user's context structure. */
@@ -365,7 +367,7 @@ static size_t find_longest_match(<%= @grammar.prefix %>context_t * context,
if (code_point == '\n') if (code_point == '\n')
{ {
attempt_match.delta_position.row++; attempt_match.delta_position.row++;
attempt_match.delta_position.col = 0u; attempt_match.delta_position.col = 1u;
} }
else else
{ {
@@ -567,7 +569,7 @@ size_t <%= @grammar.prefix %>lex(<%= @grammar.prefix %>context_t * context, <%=
*************************************************************************/ *************************************************************************/
/** Invalid position value. */ /** Invalid position value. */
#define INVALID_POSITION (<%= @grammar.prefix %>position_t){0xFFFFFFFFu, 0xFFFFFFFFu} #define INVALID_POSITION (<%= @grammar.prefix %>position_t){0u, 0u}
/** Reduce ID type. */ /** Reduce ID type. */
typedef <%= get_type_for(@parser.reduce_table.size) %> reduce_id_t; typedef <%= get_type_for(@parser.reduce_table.size) %> reduce_id_t;
+5 -3
View File
@@ -65,12 +65,12 @@ public struct <%= @grammar.prefix %>position_t
uint col; uint col;
/** Invalid position value. */ /** Invalid position value. */
enum INVALID = <%= @grammar.prefix %>position_t(0xFFFF_FFFF, 0xFFFF_FFFF); enum INVALID = <%= @grammar.prefix %>position_t(0u, 0u);
/** Return whether the position is valid. */ /** Return whether the position is valid. */
public @property bool valid() public @property bool valid()
{ {
return row != 0xFFFF_FFFFu; return row != 0u;
} }
} }
@@ -235,6 +235,8 @@ public void <%= @grammar.prefix %>context_init(<%= @grammar.prefix %>context_t *
/* Lexer initialization. */ /* Lexer initialization. */
newcontext.input = input; newcontext.input = input;
newcontext.text_position.row = 1u;
newcontext.text_position.col = 1u;
newcontext.mode = <%= @lexer.mode_id("default") %>; newcontext.mode = <%= @lexer.mode_id("default") %>;
/* Copy to the user's context structure. */ /* Copy to the user's context structure. */
@@ -534,7 +536,7 @@ private size_t find_longest_match(<%= @grammar.prefix %>context_t * context,
if (code_point == '\n') if (code_point == '\n')
{ {
attempt_match.delta_position.row++; attempt_match.delta_position.row++;
attempt_match.delta_position.col = 0u; attempt_match.delta_position.col = 1u;
} }
else else
{ {
+1 -1
View File
@@ -53,7 +53,7 @@ typedef struct
} <%= @grammar.prefix %>position_t; } <%= @grammar.prefix %>position_t;
/** Return whether the position is valid. */ /** Return whether the position is valid. */
#define <%= @grammar.prefix %>position_valid(p) ((p).row != 0xFFFFFFFFu) #define <%= @grammar.prefix %>position_valid(p) ((p).row != 0u)
/** User header code blocks. */ /** User header code blocks. */
<%= @grammar.code_blocks.fetch("header", "") %> <%= @grammar.code_blocks.fetch("header", "") %>
+7 -6
View File
@@ -641,13 +641,14 @@ This example uses the default start rule name of `Start`.
A parser rule has zero or more fields on the right side of its definition. A parser rule has zero or more fields on the right side of its definition.
Each of these fields is either a token name or a rule name. Each of these fields is either a token name or a rule name.
A field can be immediately followed by a `?` character to signify that it is
optional.
A field can optionally be followed by a `:` and then a field alias name. A field can optionally be followed by a `:` and then a field alias name.
If present, the field alias name is used to refer to the field value in user If present, the field alias name is used to refer to the field value in user
code blocks, or if AST mode is active, the field alias name is used as the code blocks, or if AST mode is active, the field alias name is used as the
field name in the generated AST node structure. field name in the generated AST node structure.
A field can be immediately followed by a `?` character to signify that it is An optional and named field must use the format `field?:name`.
optional. Example:
Another example:
``` ```
token public; token public;
@@ -655,7 +656,7 @@ token private;
token int; token int;
token ident /[a-zA-Z_][a-zA-Z_0-9]*/; token ident /[a-zA-Z_][a-zA-Z_0-9]*/;
token semicolon /;/; token semicolon /;/;
IntegerDeclaration -> Visibility? int ident:name semicolon; IntegerDeclaration -> Visibility?:visibility int ident:name semicolon;
Visibility -> public; Visibility -> public;
Visibility -> private; Visibility -> private;
``` ```
@@ -663,7 +664,7 @@ Visibility -> private;
In a parser rule code block, parser values for the right side fields are In a parser rule code block, parser values for the right side fields are
accessible as `$1` for the first field's parser value, `$2` for the second accessible as `$1` for the first field's parser value, `$2` for the second
field's parser value, etc... field's parser value, etc...
For the `IntegerDeclaration` rule, the third field value can also be referred For the `IntegerDeclaration` rule, the first field value can also be referred to as `${visibility}` and the third field value can also be referred
to as `${name}`. to as `${name}`.
The `$$` symbol accesses the output parser value for this rule. The `$$` symbol accesses the output parser value for this rule.
The above examples demonstrate how the parser values for the rule components The above examples demonstrate how the parser values for the rule components
@@ -776,7 +777,7 @@ A pointer to this instance is passed to the generated functions.
### `p_position_t` ### `p_position_t`
The `p_position_t` structure contains two fields `row` and `col`. The `p_position_t` structure contains two fields `row` and `col`.
These fields contain the 0-based row and column describing a parser position. These fields contain the 1-based row and column describing a parser position.
For D targets, the `p_position_t` structure can be checked for validity by For D targets, the `p_position_t` structure can be checked for validity by
querying the `valid` property. querying the `valid` property.
+1 -1
View File
@@ -198,7 +198,7 @@ class Propane
if @ast && ptypename if @ast && ptypename
raise Error.new("Multiple ptypes are unsupported in AST mode") raise Error.new("Multiple ptypes are unsupported in AST mode")
end end
md = consume!(/((?:#{IDENTIFIER_REGEX}(?::#{IDENTIFIER_REGEX})?\??\s*)*)\s*/, "expected rule component list") md = consume!(/((?:#{IDENTIFIER_REGEX}\??(?::#{IDENTIFIER_REGEX})?\s*)*)\s*/, "expected rule component list")
components = md[1].strip.split(/\s+/) components = md[1].strip.split(/\s+/)
if @ast if @ast
consume!(/;/, "expected `;'") consume!(/;/, "expected `;'")
+13 -2
View File
@@ -14,6 +14,7 @@ class Propane
@item_sets = [] @item_sets = []
@item_sets_set = {} @item_sets_set = {}
@warnings = Set.new @warnings = Set.new
@errors = Set.new
@options = options @options = options
start_item = Item.new(grammar.rules.first, 0) start_item = Item.new(grammar.rules.first, 0)
eval_item_sets = Set[ItemSet.new([start_item])] eval_item_sets = Set[ItemSet.new([start_item])]
@@ -41,8 +42,18 @@ class Propane
build_reduce_actions! build_reduce_actions!
build_tables! build_tables!
write_log! write_log!
errormessage = ""
if @errors.size > 0
errormessage += @errors.join("\n")
end
if @warnings.size > 0 && @options[:warnings_as_errors] if @warnings.size > 0 && @options[:warnings_as_errors]
raise Error.new("Fatal errors (-w):\n" + @warnings.join("\n")) if errormessage != ""
errormessage += "\n"
end
errormessage += "Fatal errors (-w):\n" + @warnings.join("\n")
end
if errormessage != ""
raise Error.new(errormessage)
end end
end end
@@ -171,7 +182,7 @@ class Propane
lookahead_tokens_for_rule = build_lookahead_tokens_to_reduce(reduce_rule, item_sets) lookahead_tokens_for_rule = build_lookahead_tokens_to_reduce(reduce_rule, item_sets)
lookahead_tokens_for_rule.each do |lookahead_token| lookahead_tokens_for_rule.each do |lookahead_token|
if existing_reduce_rule = reduce_actions[lookahead_token] if existing_reduce_rule = reduce_actions[lookahead_token]
raise Error.new("Error: reduce/reduce conflict (state #{item_set.id}) between rule #{existing_reduce_rule.name}##{existing_reduce_rule.id} (defined on line #{existing_reduce_rule.line_number}) and rule #{reduce_rule.name}##{reduce_rule.id} (defined on line #{reduce_rule.line_number})") @errors << "Error: reduce/reduce conflict (state #{item_set.id}) between rule #{existing_reduce_rule.name}##{existing_reduce_rule.id} (defined on line #{existing_reduce_rule.line_number}) and rule #{reduce_rule.name}##{reduce_rule.id} (defined on line #{reduce_rule.line_number}) for lookahead token #{lookahead_token}"
end end
reduce_actions[lookahead_token] = reduce_rule reduce_actions[lookahead_token] = reduce_rule
end end
+1 -1
View File
@@ -156,7 +156,7 @@ class Propane
@rules.each do |rule| @rules.each do |rule|
rule.aliases.each do |alias_name, index| rule.aliases.each do |alias_name, index|
if field_aliases[alias_name] && field_aliases[alias_name] != index if field_aliases[alias_name] && field_aliases[alias_name] != index
raise Error.new("Error: conflicting AST node field positions for alias `#{alias_name}`") raise Error.new("Error: conflicting AST node field positions for alias `#{alias_name}` in rule #{rule.name} defined on line #{rule.line_number}")
end end
field_aliases[alias_name] = index field_aliases[alias_name] = index
@ast_fields[index][alias_name] = @ast_fields[index].first[1] @ast_fields[index][alias_name] = @ast_fields[index].first[1]
+1 -1
View File
@@ -1,3 +1,3 @@
class Propane class Propane
VERSION = "1.5.1" VERSION = "2.1.0"
end end
+42
View File
@@ -689,6 +689,7 @@ EOF
results = run_propane(capture: true, language: language) results = run_propane(capture: true, language: language)
expect(results.status).to_not eq 0 expect(results.status).to_not eq 0
expect(results.stderr).to match %r{Error: reduce/reduce conflict \(state \d+\) between rule E#\d+ \(defined on line 10\) and rule F#\d+ \(defined on line 11\)} expect(results.stderr).to match %r{Error: reduce/reduce conflict \(state \d+\) between rule E#\d+ \(defined on line 10\) and rule F#\d+ \(defined on line 11\)}
expect(File.binread("spec/run/testparser.log")).to match %r{Reduce.actions:}
end end
it "provides matched text to user code blocks" do it "provides matched text to user code blocks" do
@@ -1117,6 +1118,47 @@ EOF
expect(results.status).to eq 0 expect(results.status).to eq 0
end end
it "allows naming an optional rule component in AST generation mode" do
if language == "d"
write_grammar <<EOF
ast;
<<
import std.stdio;
>>
token a;
token b;
token c;
token d;
Start -> a?:a b R?:r;
R -> c d;
R -> d c;
EOF
else
write_grammar <<EOF
ast;
<<
#include <stdio.h>
>>
token a;
token b;
token c;
token d;
Start -> a?:a b R?:r;
R -> c d;
R -> d c;
EOF
end
run_propane(language: language)
compile("spec/test_named_optional_rule_component_ast.#{language}", language: language)
results = run_test
expect(results.stderr).to eq ""
expect(results.status).to eq 0
end
it "stores token and rule positions in AST nodes" do it "stores token and rule positions in AST nodes" do
write_grammar <<EOF write_grammar <<EOF
ast; ast;
+60 -60
View File
@@ -11,92 +11,92 @@ int main()
assert(p_parse(&context) == P_SUCCESS); assert(p_parse(&context) == P_SUCCESS);
Start * start = p_result(&context); Start * start = p_result(&context);
assert_eq(1, start->pT1->pToken->position.row); assert_eq(2, start->pT1->pToken->position.row);
assert_eq(0, start->pT1->pToken->position.col); assert_eq(1, start->pT1->pToken->position.col);
assert_eq(1, start->pT1->pToken->end_position.row); assert_eq(2, start->pT1->pToken->end_position.row);
assert_eq(0, start->pT1->pToken->end_position.col); assert_eq(1, start->pT1->pToken->end_position.col);
assert(p_position_valid(start->pT1->pA->position)); assert(p_position_valid(start->pT1->pA->position));
assert_eq(2, start->pT1->pA->position.row); assert_eq(3, start->pT1->pA->position.row);
assert_eq(2, start->pT1->pA->position.col); assert_eq(3, start->pT1->pA->position.col);
assert_eq(2, start->pT1->pA->end_position.row); assert_eq(3, start->pT1->pA->end_position.row);
assert_eq(7, start->pT1->pA->end_position.col); assert_eq(8, start->pT1->pA->end_position.col);
assert_eq(1, start->pT1->position.row); assert_eq(2, start->pT1->position.row);
assert_eq(0, start->pT1->position.col); assert_eq(1, start->pT1->position.col);
assert_eq(2, start->pT1->end_position.row); assert_eq(3, start->pT1->end_position.row);
assert_eq(7, start->pT1->end_position.col); assert_eq(8, start->pT1->end_position.col);
assert_eq(1, start->position.row); assert_eq(2, start->position.row);
assert_eq(0, start->position.col); assert_eq(1, start->position.col);
assert_eq(2, start->end_position.row); assert_eq(3, start->end_position.row);
assert_eq(7, start->end_position.col); assert_eq(8, start->end_position.col);
input = "a\nbb"; input = "a\nbb";
p_context_init(&context, (uint8_t const *)input, strlen(input)); p_context_init(&context, (uint8_t const *)input, strlen(input));
assert(p_parse(&context) == P_SUCCESS); assert(p_parse(&context) == P_SUCCESS);
start = p_result(&context); start = p_result(&context);
assert_eq(0, start->pT1->pToken->position.row); assert_eq(1, start->pT1->pToken->position.row);
assert_eq(0, start->pT1->pToken->position.col); assert_eq(1, start->pT1->pToken->position.col);
assert_eq(0, start->pT1->pToken->end_position.row); assert_eq(1, start->pT1->pToken->end_position.row);
assert_eq(0, start->pT1->pToken->end_position.col); assert_eq(1, start->pT1->pToken->end_position.col);
assert(p_position_valid(start->pT1->pA->position)); assert(p_position_valid(start->pT1->pA->position));
assert_eq(1, start->pT1->pA->position.row); assert_eq(2, start->pT1->pA->position.row);
assert_eq(0, start->pT1->pA->position.col); assert_eq(1, start->pT1->pA->position.col);
assert_eq(1, start->pT1->pA->end_position.row); assert_eq(2, start->pT1->pA->end_position.row);
assert_eq(1, start->pT1->pA->end_position.col); assert_eq(2, start->pT1->pA->end_position.col);
assert_eq(0, start->pT1->position.row); assert_eq(1, start->pT1->position.row);
assert_eq(0, start->pT1->position.col); assert_eq(1, start->pT1->position.col);
assert_eq(1, start->pT1->end_position.row); assert_eq(2, start->pT1->end_position.row);
assert_eq(1, start->pT1->end_position.col); assert_eq(2, start->pT1->end_position.col);
assert_eq(0, start->position.row); assert_eq(1, start->position.row);
assert_eq(0, start->position.col); assert_eq(1, start->position.col);
assert_eq(1, start->end_position.row); assert_eq(2, start->end_position.row);
assert_eq(1, start->end_position.col); assert_eq(2, start->end_position.col);
input = "a\nc\nc"; input = "a\nc\nc";
p_context_init(&context, (uint8_t const *)input, strlen(input)); p_context_init(&context, (uint8_t const *)input, strlen(input));
assert(p_parse(&context) == P_SUCCESS); assert(p_parse(&context) == P_SUCCESS);
start = p_result(&context); start = p_result(&context);
assert_eq(0, start->pT1->pToken->position.row); assert_eq(1, start->pT1->pToken->position.row);
assert_eq(0, start->pT1->pToken->position.col); assert_eq(1, start->pT1->pToken->position.col);
assert_eq(0, start->pT1->pToken->end_position.row); assert_eq(1, start->pT1->pToken->end_position.row);
assert_eq(0, start->pT1->pToken->end_position.col); assert_eq(1, start->pT1->pToken->end_position.col);
assert(p_position_valid(start->pT1->pA->position)); assert(p_position_valid(start->pT1->pA->position));
assert_eq(1, start->pT1->pA->position.row); assert_eq(2, start->pT1->pA->position.row);
assert_eq(0, start->pT1->pA->position.col); assert_eq(1, start->pT1->pA->position.col);
assert_eq(2, start->pT1->pA->end_position.row); assert_eq(3, start->pT1->pA->end_position.row);
assert_eq(0, start->pT1->pA->end_position.col); assert_eq(1, start->pT1->pA->end_position.col);
assert_eq(0, start->pT1->position.row); assert_eq(1, start->pT1->position.row);
assert_eq(0, start->pT1->position.col); assert_eq(1, start->pT1->position.col);
assert_eq(2, start->pT1->end_position.row); assert_eq(3, start->pT1->end_position.row);
assert_eq(0, start->pT1->end_position.col); assert_eq(1, start->pT1->end_position.col);
assert_eq(0, start->position.row); assert_eq(1, start->position.row);
assert_eq(0, start->position.col); assert_eq(1, start->position.col);
assert_eq(2, start->end_position.row); assert_eq(3, start->end_position.row);
assert_eq(0, start->end_position.col); assert_eq(1, start->end_position.col);
input = "a"; input = "a";
p_context_init(&context, (uint8_t const *)input, strlen(input)); p_context_init(&context, (uint8_t const *)input, strlen(input));
assert(p_parse(&context) == P_SUCCESS); assert(p_parse(&context) == P_SUCCESS);
start = p_result(&context); start = p_result(&context);
assert_eq(0, start->pT1->pToken->position.row); assert_eq(1, start->pT1->pToken->position.row);
assert_eq(0, start->pT1->pToken->position.col); assert_eq(1, start->pT1->pToken->position.col);
assert_eq(0, start->pT1->pToken->end_position.row); assert_eq(1, start->pT1->pToken->end_position.row);
assert_eq(0, start->pT1->pToken->end_position.col); assert_eq(1, start->pT1->pToken->end_position.col);
assert(!p_position_valid(start->pT1->pA->position)); assert(!p_position_valid(start->pT1->pA->position));
assert_eq(0, start->pT1->position.row); assert_eq(1, start->pT1->position.row);
assert_eq(0, start->pT1->position.col); assert_eq(1, start->pT1->position.col);
assert_eq(0, start->pT1->end_position.row); assert_eq(1, start->pT1->end_position.row);
assert_eq(0, start->pT1->end_position.col); assert_eq(1, start->pT1->end_position.col);
assert_eq(0, start->position.row); assert_eq(1, start->position.row);
assert_eq(0, start->position.col); assert_eq(1, start->position.col);
assert_eq(0, start->end_position.row); assert_eq(1, start->end_position.row);
assert_eq(0, start->end_position.col); assert_eq(1, start->end_position.col);
return 0; return 0;
} }
+60 -60
View File
@@ -15,90 +15,90 @@ unittest
assert(p_parse(&context) == P_SUCCESS); assert(p_parse(&context) == P_SUCCESS);
Start * start = p_result(&context); Start * start = p_result(&context);
assert_eq(1, start.pT1.pToken.position.row); assert_eq(2, start.pT1.pToken.position.row);
assert_eq(0, start.pT1.pToken.position.col); assert_eq(1, start.pT1.pToken.position.col);
assert_eq(1, start.pT1.pToken.end_position.row); assert_eq(2, start.pT1.pToken.end_position.row);
assert_eq(0, start.pT1.pToken.end_position.col); assert_eq(1, start.pT1.pToken.end_position.col);
assert(start.pT1.pA.position.valid); assert(start.pT1.pA.position.valid);
assert_eq(2, start.pT1.pA.position.row); assert_eq(3, start.pT1.pA.position.row);
assert_eq(2, start.pT1.pA.position.col); assert_eq(3, start.pT1.pA.position.col);
assert_eq(2, start.pT1.pA.end_position.row); assert_eq(3, start.pT1.pA.end_position.row);
assert_eq(7, start.pT1.pA.end_position.col); assert_eq(8, start.pT1.pA.end_position.col);
assert_eq(1, start.pT1.position.row); assert_eq(2, start.pT1.position.row);
assert_eq(0, start.pT1.position.col); assert_eq(1, start.pT1.position.col);
assert_eq(2, start.pT1.end_position.row); assert_eq(3, start.pT1.end_position.row);
assert_eq(7, start.pT1.end_position.col); assert_eq(8, start.pT1.end_position.col);
assert_eq(1, start.position.row); assert_eq(2, start.position.row);
assert_eq(0, start.position.col); assert_eq(1, start.position.col);
assert_eq(2, start.end_position.row); assert_eq(3, start.end_position.row);
assert_eq(7, start.end_position.col); assert_eq(8, start.end_position.col);
input = "a\nbb"; input = "a\nbb";
p_context_init(&context, input); p_context_init(&context, input);
assert(p_parse(&context) == P_SUCCESS); assert(p_parse(&context) == P_SUCCESS);
start = p_result(&context); start = p_result(&context);
assert_eq(0, start.pT1.pToken.position.row); assert_eq(1, start.pT1.pToken.position.row);
assert_eq(0, start.pT1.pToken.position.col); assert_eq(1, start.pT1.pToken.position.col);
assert_eq(0, start.pT1.pToken.end_position.row); assert_eq(1, start.pT1.pToken.end_position.row);
assert_eq(0, start.pT1.pToken.end_position.col); assert_eq(1, start.pT1.pToken.end_position.col);
assert(start.pT1.pA.position.valid); assert(start.pT1.pA.position.valid);
assert_eq(1, start.pT1.pA.position.row); assert_eq(2, start.pT1.pA.position.row);
assert_eq(0, start.pT1.pA.position.col); assert_eq(1, start.pT1.pA.position.col);
assert_eq(1, start.pT1.pA.end_position.row); assert_eq(2, start.pT1.pA.end_position.row);
assert_eq(1, start.pT1.pA.end_position.col); assert_eq(2, start.pT1.pA.end_position.col);
assert_eq(0, start.pT1.position.row); assert_eq(1, start.pT1.position.row);
assert_eq(0, start.pT1.position.col); assert_eq(1, start.pT1.position.col);
assert_eq(1, start.pT1.end_position.row); assert_eq(2, start.pT1.end_position.row);
assert_eq(1, start.pT1.end_position.col); assert_eq(2, start.pT1.end_position.col);
assert_eq(0, start.position.row); assert_eq(1, start.position.row);
assert_eq(0, start.position.col); assert_eq(1, start.position.col);
assert_eq(1, start.end_position.row); assert_eq(2, start.end_position.row);
assert_eq(1, start.end_position.col); assert_eq(2, start.end_position.col);
input = "a\nc\nc"; input = "a\nc\nc";
p_context_init(&context, input); p_context_init(&context, input);
assert(p_parse(&context) == P_SUCCESS); assert(p_parse(&context) == P_SUCCESS);
start = p_result(&context); start = p_result(&context);
assert_eq(0, start.pT1.pToken.position.row); assert_eq(1, start.pT1.pToken.position.row);
assert_eq(0, start.pT1.pToken.position.col); assert_eq(1, start.pT1.pToken.position.col);
assert_eq(0, start.pT1.pToken.end_position.row); assert_eq(1, start.pT1.pToken.end_position.row);
assert_eq(0, start.pT1.pToken.end_position.col); assert_eq(1, start.pT1.pToken.end_position.col);
assert(start.pT1.pA.position.valid); assert(start.pT1.pA.position.valid);
assert_eq(1, start.pT1.pA.position.row); assert_eq(2, start.pT1.pA.position.row);
assert_eq(0, start.pT1.pA.position.col); assert_eq(1, start.pT1.pA.position.col);
assert_eq(2, start.pT1.pA.end_position.row); assert_eq(3, start.pT1.pA.end_position.row);
assert_eq(0, start.pT1.pA.end_position.col); assert_eq(1, start.pT1.pA.end_position.col);
assert_eq(0, start.pT1.position.row); assert_eq(1, start.pT1.position.row);
assert_eq(0, start.pT1.position.col); assert_eq(1, start.pT1.position.col);
assert_eq(2, start.pT1.end_position.row); assert_eq(3, start.pT1.end_position.row);
assert_eq(0, start.pT1.end_position.col); assert_eq(1, start.pT1.end_position.col);
assert_eq(0, start.position.row); assert_eq(1, start.position.row);
assert_eq(0, start.position.col); assert_eq(1, start.position.col);
assert_eq(2, start.end_position.row); assert_eq(3, start.end_position.row);
assert_eq(0, start.end_position.col); assert_eq(1, start.end_position.col);
input = "a"; input = "a";
p_context_init(&context, input); p_context_init(&context, input);
assert(p_parse(&context) == P_SUCCESS); assert(p_parse(&context) == P_SUCCESS);
start = p_result(&context); start = p_result(&context);
assert_eq(0, start.pT1.pToken.position.row); assert_eq(1, start.pT1.pToken.position.row);
assert_eq(0, start.pT1.pToken.position.col); assert_eq(1, start.pT1.pToken.position.col);
assert_eq(0, start.pT1.pToken.end_position.row); assert_eq(1, start.pT1.pToken.end_position.row);
assert_eq(0, start.pT1.pToken.end_position.col); assert_eq(1, start.pT1.pToken.end_position.col);
assert(!start.pT1.pA.position.valid); assert(!start.pT1.pA.position.valid);
assert_eq(0, start.pT1.position.row); assert_eq(1, start.pT1.position.row);
assert_eq(0, start.pT1.position.col); assert_eq(1, start.pT1.position.col);
assert_eq(0, start.pT1.end_position.row); assert_eq(1, start.pT1.end_position.row);
assert_eq(0, start.pT1.end_position.col); assert_eq(1, start.pT1.end_position.col);
assert_eq(0, start.position.row); assert_eq(1, start.position.row);
assert_eq(0, start.position.col); assert_eq(1, start.position.col);
assert_eq(0, start.end_position.row); assert_eq(1, start.end_position.row);
assert_eq(0, start.end_position.col); assert_eq(1, start.end_position.col);
} }
+56 -56
View File
@@ -11,74 +11,74 @@ int main()
assert(p_parse(&context) == P_SUCCESS); assert(p_parse(&context) == P_SUCCESS);
Start * start = p_result(&context); Start * start = p_result(&context);
assert_eq(0, start->pT1->pToken->position.row); assert_eq(1, start->pT1->pToken->position.row);
assert_eq(0, start->pT1->pToken->position.col); assert_eq(1, start->pT1->pToken->position.col);
assert_eq(0, start->pT1->pToken->end_position.row); assert_eq(1, start->pT1->pToken->end_position.row);
assert_eq(0, start->pT1->pToken->end_position.col); assert_eq(1, start->pT1->pToken->end_position.col);
assert_eq(0, start->pT1->position.row); assert_eq(1, start->pT1->position.row);
assert_eq(0, start->pT1->position.col); assert_eq(1, start->pT1->position.col);
assert_eq(0, start->pT1->end_position.row); assert_eq(1, start->pT1->end_position.row);
assert_eq(0, start->pT1->end_position.col); assert_eq(1, start->pT1->end_position.col);
assert_eq(0, start->pT2->pToken->position.row); assert_eq(1, start->pT2->pToken->position.row);
assert_eq(1, start->pT2->pToken->position.col); assert_eq(2, start->pT2->pToken->position.col);
assert_eq(0, start->pT2->pToken->end_position.row); assert_eq(1, start->pT2->pToken->end_position.row);
assert_eq(2, start->pT2->pToken->end_position.col); assert_eq(3, start->pT2->pToken->end_position.col);
assert_eq(0, start->pT2->position.row); assert_eq(1, start->pT2->position.row);
assert_eq(1, start->pT2->position.col); assert_eq(2, start->pT2->position.col);
assert_eq(0, start->pT2->end_position.row); assert_eq(1, start->pT2->end_position.row);
assert_eq(2, start->pT2->end_position.col); assert_eq(3, start->pT2->end_position.col);
assert_eq(0, start->pT3->pToken->position.row); assert_eq(1, start->pT3->pToken->position.row);
assert_eq(3, start->pT3->pToken->position.col); assert_eq(4, start->pT3->pToken->position.col);
assert_eq(0, start->pT3->pToken->end_position.row); assert_eq(1, start->pT3->pToken->end_position.row);
assert_eq(5, start->pT3->pToken->end_position.col); assert_eq(6, start->pT3->pToken->end_position.col);
assert_eq(0, start->pT3->position.row); assert_eq(1, start->pT3->position.row);
assert_eq(3, start->pT3->position.col); assert_eq(4, start->pT3->position.col);
assert_eq(0, start->pT3->end_position.row); assert_eq(1, start->pT3->end_position.row);
assert_eq(5, start->pT3->end_position.col); assert_eq(6, start->pT3->end_position.col);
assert_eq(0, start->position.row); assert_eq(1, start->position.row);
assert_eq(0, start->position.col); assert_eq(1, start->position.col);
assert_eq(0, start->end_position.row); assert_eq(1, start->end_position.row);
assert_eq(5, start->end_position.col); assert_eq(6, start->end_position.col);
input = "\n\n bb\nc\ncc\n\n a"; input = "\n\n bb\nc\ncc\n\n a";
p_context_init(&context, (uint8_t const *)input, strlen(input)); p_context_init(&context, (uint8_t const *)input, strlen(input));
assert(p_parse(&context) == P_SUCCESS); assert(p_parse(&context) == P_SUCCESS);
start = p_result(&context); start = p_result(&context);
assert_eq(2, start->pT1->pToken->position.row); assert_eq(3, start->pT1->pToken->position.row);
assert_eq(2, start->pT1->pToken->position.col); assert_eq(3, start->pT1->pToken->position.col);
assert_eq(2, start->pT1->pToken->end_position.row); assert_eq(3, start->pT1->pToken->end_position.row);
assert_eq(3, start->pT1->pToken->end_position.col); assert_eq(4, start->pT1->pToken->end_position.col);
assert_eq(2, start->pT1->position.row); assert_eq(3, start->pT1->position.row);
assert_eq(2, start->pT1->position.col); assert_eq(3, start->pT1->position.col);
assert_eq(2, start->pT1->end_position.row); assert_eq(3, start->pT1->end_position.row);
assert_eq(3, start->pT1->end_position.col); assert_eq(4, start->pT1->end_position.col);
assert_eq(3, start->pT2->pToken->position.row); assert_eq(4, start->pT2->pToken->position.row);
assert_eq(0, start->pT2->pToken->position.col); assert_eq(1, start->pT2->pToken->position.col);
assert_eq(4, start->pT2->pToken->end_position.row); assert_eq(5, start->pT2->pToken->end_position.row);
assert_eq(1, start->pT2->pToken->end_position.col); assert_eq(2, start->pT2->pToken->end_position.col);
assert_eq(3, start->pT2->position.row); assert_eq(4, start->pT2->position.row);
assert_eq(0, start->pT2->position.col); assert_eq(1, start->pT2->position.col);
assert_eq(4, start->pT2->end_position.row); assert_eq(5, start->pT2->end_position.row);
assert_eq(1, start->pT2->end_position.col); assert_eq(2, start->pT2->end_position.col);
assert_eq(6, start->pT3->pToken->position.row); assert_eq(7, start->pT3->pToken->position.row);
assert_eq(5, start->pT3->pToken->position.col); assert_eq(6, start->pT3->pToken->position.col);
assert_eq(6, start->pT3->pToken->end_position.row); assert_eq(7, start->pT3->pToken->end_position.row);
assert_eq(5, start->pT3->pToken->end_position.col); assert_eq(6, start->pT3->pToken->end_position.col);
assert_eq(6, start->pT3->position.row); assert_eq(7, start->pT3->position.row);
assert_eq(5, start->pT3->position.col); assert_eq(6, start->pT3->position.col);
assert_eq(6, start->pT3->end_position.row); assert_eq(7, start->pT3->end_position.row);
assert_eq(5, start->pT3->end_position.col); assert_eq(6, start->pT3->end_position.col);
assert_eq(2, start->position.row); assert_eq(3, start->position.row);
assert_eq(2, start->position.col); assert_eq(3, start->position.col);
assert_eq(6, start->end_position.row); assert_eq(7, start->end_position.row);
assert_eq(5, start->end_position.col); assert_eq(6, start->end_position.col);
return 0; return 0;
} }
+56 -56
View File
@@ -15,72 +15,72 @@ unittest
assert(p_parse(&context) == P_SUCCESS); assert(p_parse(&context) == P_SUCCESS);
Start * start = p_result(&context); Start * start = p_result(&context);
assert_eq(0, start.pT1.pToken.position.row); assert_eq(1, start.pT1.pToken.position.row);
assert_eq(0, start.pT1.pToken.position.col); assert_eq(1, start.pT1.pToken.position.col);
assert_eq(0, start.pT1.pToken.end_position.row); assert_eq(1, start.pT1.pToken.end_position.row);
assert_eq(0, start.pT1.pToken.end_position.col); assert_eq(1, start.pT1.pToken.end_position.col);
assert_eq(0, start.pT1.position.row); assert_eq(1, start.pT1.position.row);
assert_eq(0, start.pT1.position.col); assert_eq(1, start.pT1.position.col);
assert_eq(0, start.pT1.end_position.row); assert_eq(1, start.pT1.end_position.row);
assert_eq(0, start.pT1.end_position.col); assert_eq(1, start.pT1.end_position.col);
assert_eq(0, start.pT2.pToken.position.row); assert_eq(1, start.pT2.pToken.position.row);
assert_eq(1, start.pT2.pToken.position.col); assert_eq(2, start.pT2.pToken.position.col);
assert_eq(0, start.pT2.pToken.end_position.row); assert_eq(1, start.pT2.pToken.end_position.row);
assert_eq(2, start.pT2.pToken.end_position.col); assert_eq(3, start.pT2.pToken.end_position.col);
assert_eq(0, start.pT2.position.row); assert_eq(1, start.pT2.position.row);
assert_eq(1, start.pT2.position.col); assert_eq(2, start.pT2.position.col);
assert_eq(0, start.pT2.end_position.row); assert_eq(1, start.pT2.end_position.row);
assert_eq(2, start.pT2.end_position.col); assert_eq(3, start.pT2.end_position.col);
assert_eq(0, start.pT3.pToken.position.row); assert_eq(1, start.pT3.pToken.position.row);
assert_eq(3, start.pT3.pToken.position.col); assert_eq(4, start.pT3.pToken.position.col);
assert_eq(0, start.pT3.pToken.end_position.row); assert_eq(1, start.pT3.pToken.end_position.row);
assert_eq(5, start.pT3.pToken.end_position.col); assert_eq(6, start.pT3.pToken.end_position.col);
assert_eq(0, start.pT3.position.row); assert_eq(1, start.pT3.position.row);
assert_eq(3, start.pT3.position.col); assert_eq(4, start.pT3.position.col);
assert_eq(0, start.pT3.end_position.row); assert_eq(1, start.pT3.end_position.row);
assert_eq(5, start.pT3.end_position.col); assert_eq(6, start.pT3.end_position.col);
assert_eq(0, start.position.row); assert_eq(1, start.position.row);
assert_eq(0, start.position.col); assert_eq(1, start.position.col);
assert_eq(0, start.end_position.row); assert_eq(1, start.end_position.row);
assert_eq(5, start.end_position.col); assert_eq(6, start.end_position.col);
input = "\n\n bb\nc\ncc\n\n a"; input = "\n\n bb\nc\ncc\n\n a";
p_context_init(&context, input); p_context_init(&context, input);
assert(p_parse(&context) == P_SUCCESS); assert(p_parse(&context) == P_SUCCESS);
start = p_result(&context); start = p_result(&context);
assert_eq(2, start.pT1.pToken.position.row); assert_eq(3, start.pT1.pToken.position.row);
assert_eq(2, start.pT1.pToken.position.col); assert_eq(3, start.pT1.pToken.position.col);
assert_eq(2, start.pT1.pToken.end_position.row); assert_eq(3, start.pT1.pToken.end_position.row);
assert_eq(3, start.pT1.pToken.end_position.col); assert_eq(4, start.pT1.pToken.end_position.col);
assert_eq(2, start.pT1.position.row); assert_eq(3, start.pT1.position.row);
assert_eq(2, start.pT1.position.col); assert_eq(3, start.pT1.position.col);
assert_eq(2, start.pT1.end_position.row); assert_eq(3, start.pT1.end_position.row);
assert_eq(3, start.pT1.end_position.col); assert_eq(4, start.pT1.end_position.col);
assert_eq(3, start.pT2.pToken.position.row); assert_eq(4, start.pT2.pToken.position.row);
assert_eq(0, start.pT2.pToken.position.col); assert_eq(1, start.pT2.pToken.position.col);
assert_eq(4, start.pT2.pToken.end_position.row); assert_eq(5, start.pT2.pToken.end_position.row);
assert_eq(1, start.pT2.pToken.end_position.col); assert_eq(2, start.pT2.pToken.end_position.col);
assert_eq(3, start.pT2.position.row); assert_eq(4, start.pT2.position.row);
assert_eq(0, start.pT2.position.col); assert_eq(1, start.pT2.position.col);
assert_eq(4, start.pT2.end_position.row); assert_eq(5, start.pT2.end_position.row);
assert_eq(1, start.pT2.end_position.col); assert_eq(2, start.pT2.end_position.col);
assert_eq(6, start.pT3.pToken.position.row); assert_eq(7, start.pT3.pToken.position.row);
assert_eq(5, start.pT3.pToken.position.col); assert_eq(6, start.pT3.pToken.position.col);
assert_eq(6, start.pT3.pToken.end_position.row); assert_eq(7, start.pT3.pToken.end_position.row);
assert_eq(5, start.pT3.pToken.end_position.col); assert_eq(6, start.pT3.pToken.end_position.col);
assert_eq(6, start.pT3.position.row); assert_eq(7, start.pT3.position.row);
assert_eq(5, start.pT3.position.col); assert_eq(6, start.pT3.position.col);
assert_eq(6, start.pT3.end_position.row); assert_eq(7, start.pT3.end_position.row);
assert_eq(5, start.pT3.end_position.col); assert_eq(6, start.pT3.end_position.col);
assert_eq(2, start.position.row); assert_eq(3, start.position.row);
assert_eq(2, start.position.col); assert_eq(3, start.position.col);
assert_eq(6, start.end_position.row); assert_eq(7, start.end_position.row);
assert_eq(5, start.end_position.col); assert_eq(6, start.end_position.col);
} }
+8 -8
View File
@@ -12,28 +12,28 @@ int main()
input = "a\n123\na a"; input = "a\n123\na a";
p_context_init(&context, (uint8_t const *)input, strlen(input)); p_context_init(&context, (uint8_t const *)input, strlen(input));
assert(p_parse(&context) == P_UNEXPECTED_TOKEN); assert(p_parse(&context) == P_UNEXPECTED_TOKEN);
assert(p_position(&context).row == 2); assert(p_position(&context).row == 3);
assert(p_position(&context).col == 3); assert(p_position(&context).col == 4);
assert(p_token(&context) == TOKEN_a); assert(p_token(&context) == TOKEN_a);
input = "12"; input = "12";
p_context_init(&context, (uint8_t const *)input, strlen(input)); p_context_init(&context, (uint8_t const *)input, strlen(input));
assert(p_parse(&context) == P_UNEXPECTED_TOKEN); assert(p_parse(&context) == P_UNEXPECTED_TOKEN);
assert(p_position(&context).row == 0); assert(p_position(&context).row == 1);
assert(p_position(&context).col == 0); assert(p_position(&context).col == 1);
assert(p_token(&context) == TOKEN_num); assert(p_token(&context) == TOKEN_num);
input = "a 12\n\nab"; input = "a 12\n\nab";
p_context_init(&context, (uint8_t const *)input, strlen(input)); p_context_init(&context, (uint8_t const *)input, strlen(input));
assert(p_parse(&context) == P_UNEXPECTED_INPUT); assert(p_parse(&context) == P_UNEXPECTED_INPUT);
assert(p_position(&context).row == 2); assert(p_position(&context).row == 3);
assert(p_position(&context).col == 1); assert(p_position(&context).col == 2);
input = "a 12\n\na\n\n77\na \xAA"; input = "a 12\n\na\n\n77\na \xAA";
p_context_init(&context, (uint8_t const *)input, strlen(input)); p_context_init(&context, (uint8_t const *)input, strlen(input));
assert(p_parse(&context) == P_DECODE_ERROR); assert(p_parse(&context) == P_DECODE_ERROR);
assert(p_position(&context).row == 5); assert(p_position(&context).row == 6);
assert(p_position(&context).col == 4); assert(p_position(&context).col == 5);
assert(strcmp(p_token_names[TOKEN_a], "a") == 0); assert(strcmp(p_token_names[TOKEN_a], "a") == 0);
assert(strcmp(p_token_names[TOKEN_num], "num") == 0); assert(strcmp(p_token_names[TOKEN_num], "num") == 0);
+4 -4
View File
@@ -16,24 +16,24 @@ unittest
input = "a\n123\na a"; input = "a\n123\na a";
p_context_init(&context, input); p_context_init(&context, input);
assert(p_parse(&context) == P_UNEXPECTED_TOKEN); assert(p_parse(&context) == P_UNEXPECTED_TOKEN);
assert(p_position(&context) == p_position_t(2, 3)); assert(p_position(&context) == p_position_t(3, 4));
assert(p_token(&context) == TOKEN_a); assert(p_token(&context) == TOKEN_a);
input = "12"; input = "12";
p_context_init(&context, input); p_context_init(&context, input);
assert(p_parse(&context) == P_UNEXPECTED_TOKEN); assert(p_parse(&context) == P_UNEXPECTED_TOKEN);
assert(p_position(&context) == p_position_t(0, 0)); assert(p_position(&context) == p_position_t(1, 1));
assert(p_token(&context) == TOKEN_num); assert(p_token(&context) == TOKEN_num);
input = "a 12\n\nab"; input = "a 12\n\nab";
p_context_init(&context, input); p_context_init(&context, input);
assert(p_parse(&context) == P_UNEXPECTED_INPUT); assert(p_parse(&context) == P_UNEXPECTED_INPUT);
assert(p_position(&context) == p_position_t(2, 1)); assert(p_position(&context) == p_position_t(3, 2));
input = "a 12\n\na\n\n77\na \xAA"; input = "a 12\n\na\n\n77\na \xAA";
p_context_init(&context, input); p_context_init(&context, input);
assert(p_parse(&context) == P_DECODE_ERROR); assert(p_parse(&context) == P_DECODE_ERROR);
assert(p_position(&context) == p_position_t(5, 4)); assert(p_position(&context) == p_position_t(6, 5));
assert(p_token_names[TOKEN_a] == "a"); assert(p_token_names[TOKEN_a] == "a");
assert(p_token_names[TOKEN_num] == "num"); assert(p_token_names[TOKEN_num] == "num");
+36 -36
View File
@@ -41,68 +41,68 @@ int main()
p_context_t context; p_context_t context;
p_context_init(&context, (uint8_t const *)input, strlen(input)); p_context_init(&context, (uint8_t const *)input, strlen(input));
assert(p_lex(&context, &token_info) == P_SUCCESS); assert(p_lex(&context, &token_info) == P_SUCCESS);
assert(token_info.position.row == 0u); assert(token_info.position.row == 1u);
assert(token_info.position.col == 0u); assert(token_info.position.col == 1u);
assert(token_info.end_position.row == 0u); assert(token_info.end_position.row == 1u);
assert(token_info.end_position.col == 0u); assert(token_info.end_position.col == 1u);
assert(token_info.length == 1u); assert(token_info.length == 1u);
assert(token_info.token == TOKEN_int); assert(token_info.token == TOKEN_int);
assert(p_lex(&context, &token_info) == P_SUCCESS); assert(p_lex(&context, &token_info) == P_SUCCESS);
assert(token_info.position.row == 0u); assert(token_info.position.row == 1u);
assert(token_info.position.col == 2u); assert(token_info.position.col == 3u);
assert(token_info.end_position.row == 0u); assert(token_info.end_position.row == 1u);
assert(token_info.end_position.col == 2u); assert(token_info.end_position.col == 3u);
assert(token_info.length == 1u); assert(token_info.length == 1u);
assert(token_info.token == TOKEN_plus); assert(token_info.token == TOKEN_plus);
assert(p_lex(&context, &token_info) == P_SUCCESS); assert(p_lex(&context, &token_info) == P_SUCCESS);
assert(token_info.position.row == 0u); assert(token_info.position.row == 1u);
assert(token_info.position.col == 4u); assert(token_info.position.col == 5u);
assert(token_info.end_position.row == 0u); assert(token_info.end_position.row == 1u);
assert(token_info.end_position.col == 4u); assert(token_info.end_position.col == 5u);
assert(token_info.length == 1u); assert(token_info.length == 1u);
assert(token_info.token == TOKEN_int); assert(token_info.token == TOKEN_int);
assert(p_lex(&context, &token_info) == P_SUCCESS); assert(p_lex(&context, &token_info) == P_SUCCESS);
assert(token_info.position.row == 0u); assert(token_info.position.row == 1u);
assert(token_info.position.col == 6u); assert(token_info.position.col == 7u);
assert(token_info.end_position.row == 0u); assert(token_info.end_position.row == 1u);
assert(token_info.end_position.col == 6u); assert(token_info.end_position.col == 7u);
assert(token_info.length == 1u); assert(token_info.length == 1u);
assert(token_info.token == TOKEN_times); assert(token_info.token == TOKEN_times);
assert(p_lex(&context, &token_info) == P_SUCCESS); assert(p_lex(&context, &token_info) == P_SUCCESS);
assert(token_info.position.row == 1u); assert(token_info.position.row == 2u);
assert(token_info.position.col == 0u); assert(token_info.position.col == 1u);
assert(token_info.end_position.row == 1u); assert(token_info.end_position.row == 2u);
assert(token_info.end_position.col == 2u); assert(token_info.end_position.col == 3u);
assert(token_info.length == 3u); assert(token_info.length == 3u);
assert(token_info.token == TOKEN_int); assert(token_info.token == TOKEN_int);
assert(p_lex(&context, &token_info) == P_SUCCESS); assert(p_lex(&context, &token_info) == P_SUCCESS);
assert(token_info.position.row == 1u); assert(token_info.position.row == 2u);
assert(token_info.position.col == 4u); assert(token_info.position.col == 5u);
assert(token_info.end_position.row == 1u); assert(token_info.end_position.row == 2u);
assert(token_info.end_position.col == 4u); assert(token_info.end_position.col == 5u);
assert(token_info.length == 1u); assert(token_info.length == 1u);
assert(token_info.token == TOKEN_plus); assert(token_info.token == TOKEN_plus);
assert(p_lex(&context, &token_info) == P_SUCCESS); assert(p_lex(&context, &token_info) == P_SUCCESS);
assert(token_info.position.row == 1u); assert(token_info.position.row == 2u);
assert(token_info.position.col == 6u); assert(token_info.position.col == 7u);
assert(token_info.end_position.row == 1u); assert(token_info.end_position.row == 2u);
assert(token_info.end_position.col == 8u); assert(token_info.end_position.col == 9u);
assert(token_info.length == 3u); assert(token_info.length == 3u);
assert(token_info.token == TOKEN_int); assert(token_info.token == TOKEN_int);
assert(p_lex(&context, &token_info) == P_SUCCESS); assert(p_lex(&context, &token_info) == P_SUCCESS);
assert(token_info.position.row == 1u); assert(token_info.position.row == 2u);
assert(token_info.position.col == 9u); assert(token_info.position.col == 10u);
assert(token_info.end_position.row == 1u); assert(token_info.end_position.row == 2u);
assert(token_info.end_position.col == 9u); assert(token_info.end_position.col == 10u);
assert(token_info.length == 0u); assert(token_info.length == 0u);
assert(token_info.token == TOKEN___EOF); assert(token_info.token == TOKEN___EOF);
p_context_init(&context, (uint8_t const *)"", 0u); p_context_init(&context, (uint8_t const *)"", 0u);
assert(p_lex(&context, &token_info) == P_SUCCESS); assert(p_lex(&context, &token_info) == P_SUCCESS);
assert(token_info.position.row == 0u); assert(token_info.position.row == 1u);
assert(token_info.position.col == 0u); assert(token_info.position.col == 1u);
assert(token_info.end_position.row == 0u); assert(token_info.end_position.row == 1u);
assert(token_info.end_position.col == 0u); assert(token_info.end_position.col == 1u);
assert(token_info.length == 0u); assert(token_info.length == 0u);
assert(token_info.token == TOKEN___EOF); assert(token_info.token == TOKEN___EOF);
+9 -9
View File
@@ -47,23 +47,23 @@ unittest
p_context_t context; p_context_t context;
p_context_init(&context, input); p_context_init(&context, input);
assert(p_lex(&context, &token_info) == P_SUCCESS); assert(p_lex(&context, &token_info) == P_SUCCESS);
assert(token_info == p_token_info_t(p_position_t(0, 0), p_position_t(0, 0), 1, TOKEN_int)); assert(token_info == p_token_info_t(p_position_t(1, 1), p_position_t(1, 1), 1, TOKEN_int));
assert(p_lex(&context, &token_info) == P_SUCCESS); assert(p_lex(&context, &token_info) == P_SUCCESS);
assert(token_info == p_token_info_t(p_position_t(0, 2), p_position_t(0, 2), 1, TOKEN_plus)); assert(token_info == p_token_info_t(p_position_t(1, 3), p_position_t(1, 3), 1, TOKEN_plus));
assert(p_lex(&context, &token_info) == P_SUCCESS); assert(p_lex(&context, &token_info) == P_SUCCESS);
assert(token_info == p_token_info_t(p_position_t(0, 4), p_position_t(0, 4), 1, TOKEN_int)); assert(token_info == p_token_info_t(p_position_t(1, 5), p_position_t(1, 5), 1, TOKEN_int));
assert(p_lex(&context, &token_info) == P_SUCCESS); assert(p_lex(&context, &token_info) == P_SUCCESS);
assert(token_info == p_token_info_t(p_position_t(0, 6), p_position_t(0, 6), 1, TOKEN_times)); assert(token_info == p_token_info_t(p_position_t(1, 7), p_position_t(1, 7), 1, TOKEN_times));
assert(p_lex(&context, &token_info) == P_SUCCESS); assert(p_lex(&context, &token_info) == P_SUCCESS);
assert(token_info == p_token_info_t(p_position_t(1, 0), p_position_t(1, 2), 3, TOKEN_int)); assert(token_info == p_token_info_t(p_position_t(2, 1), p_position_t(2, 3), 3, TOKEN_int));
assert(p_lex(&context, &token_info) == P_SUCCESS); assert(p_lex(&context, &token_info) == P_SUCCESS);
assert(token_info == p_token_info_t(p_position_t(1, 4), p_position_t(1, 4), 1, TOKEN_plus)); assert(token_info == p_token_info_t(p_position_t(2, 5), p_position_t(2, 5), 1, TOKEN_plus));
assert(p_lex(&context, &token_info) == P_SUCCESS); assert(p_lex(&context, &token_info) == P_SUCCESS);
assert(token_info == p_token_info_t(p_position_t(1, 6), p_position_t(1, 8), 3, TOKEN_int)); assert(token_info == p_token_info_t(p_position_t(2, 7), p_position_t(2, 9), 3, TOKEN_int));
assert(p_lex(&context, &token_info) == P_SUCCESS); assert(p_lex(&context, &token_info) == P_SUCCESS);
assert(token_info == p_token_info_t(p_position_t(1, 9), p_position_t(1, 9), 0, TOKEN___EOF)); assert(token_info == p_token_info_t(p_position_t(2, 10), p_position_t(2, 10), 0, TOKEN___EOF));
p_context_init(&context, ""); p_context_init(&context, "");
assert(p_lex(&context, &token_info) == P_SUCCESS); assert(p_lex(&context, &token_info) == P_SUCCESS);
assert(token_info == p_token_info_t(p_position_t(0, 0), p_position_t(0, 0), 0, TOKEN___EOF)); assert(token_info == p_token_info_t(p_position_t(1, 1), p_position_t(1, 1), 0, TOKEN___EOF));
} }
@@ -0,0 +1,45 @@
#include "testparser.h"
#include <assert.h>
#include <string.h>
#include "testutils.h"
int main()
{
char const * input = "b";
p_context_t context;
p_context_init(&context, (uint8_t const *)input, strlen(input));
assert(p_parse(&context) == P_SUCCESS);
Start * start = p_result(&context);
assert(start->a == NULL);
assert(start->pToken2 != NULL);
assert_eq(TOKEN_b, start->pToken2->token);
assert(start->pR3 == NULL);
assert(start->pR == NULL);
assert(start->r == NULL);
input = "abcd";
p_context_init(&context, (uint8_t const *)input, strlen(input));
assert(p_parse(&context) == P_SUCCESS);
start = p_result(&context);
assert(start->a != NULL);
assert_eq(TOKEN_a, start->pToken1->token);
assert(start->pToken2 != NULL);
assert(start->pR3 != NULL);
assert(start->pR != NULL);
assert(start->r != NULL);
assert(start->pR == start->pR3);
assert(start->pR == start->r);
assert_eq(TOKEN_c, start->pR->pToken1->token);
input = "bdc";
p_context_init(&context, (uint8_t const *)input, strlen(input));
assert(p_parse(&context) == P_SUCCESS);
start = p_result(&context);
assert(start->a == NULL);
assert(start->pToken2 != NULL);
assert(start->r != NULL);
assert_eq(TOKEN_d, start->pR->pToken1->token);
return 0;
}
@@ -0,0 +1,46 @@
import testparser;
import std.stdio;
import testutils;
int main()
{
return 0;
}
unittest
{
string input = "b";
p_context_t context;
p_context_init(&context, input);
assert(p_parse(&context) == P_SUCCESS);
Start * start = p_result(&context);
assert(start.pToken1 is null);
assert(start.pToken2 !is null);
assert_eq(TOKEN_b, start.pToken2.token);
assert(start.pR3 is null);
assert(start.pR is null);
assert(start.r is null);
input = "abcd";
p_context_init(&context, input);
assert(p_parse(&context) == P_SUCCESS);
start = p_result(&context);
assert(start.pToken1 != null);
assert_eq(TOKEN_a, start.pToken1.token);
assert(start.pToken2 != null);
assert(start.pR3 != null);
assert(start.pR != null);
assert(start.r != null);
assert(start.pR == start.pR3);
assert(start.pR == start.r);
assert_eq(TOKEN_c, start.pR.pToken1.token);
input = "bdc";
p_context_init(&context, input);
assert(p_parse(&context) == P_SUCCESS);
start = p_result(&context);
assert(start.pToken1 is null);
assert(start.pToken2 !is null);
assert(start.pR !is null);
assert_eq(TOKEN_d, start.pR.pToken1.token);
}
+2 -2
View File
@@ -8,8 +8,8 @@ int main()
p_context_t context; p_context_t context;
p_context_init(&context, (uint8_t const *)input, strlen(input)); p_context_init(&context, (uint8_t const *)input, strlen(input));
assert(p_parse(&context) == P_UNEXPECTED_TOKEN); assert(p_parse(&context) == P_UNEXPECTED_TOKEN);
assert(p_position(&context).row == 0); assert(p_position(&context).row == 1);
assert(p_position(&context).col == 1); assert(p_position(&context).col == 2);
assert(context.token == TOKEN___EOF); assert(context.token == TOKEN___EOF);
input = "a b"; input = "a b";
+1 -1
View File
@@ -12,7 +12,7 @@ unittest
p_context_t context; p_context_t context;
p_context_init(&context, input); p_context_init(&context, input);
assert(p_parse(&context) == P_UNEXPECTED_TOKEN); assert(p_parse(&context) == P_UNEXPECTED_TOKEN);
assert(p_position(&context) == p_position_t(0, 1)); assert(p_position(&context) == p_position_t(1, 2));
assert(context.token == TOKEN___EOF); assert(context.token == TOKEN___EOF);
input = "a b"; input = "a b";