Skip to content

Commit

Permalink
Fix parsing ambiguity with properties.
Browse files Browse the repository at this point in the history
In the past, we had special-cased properties in our Flex/Bison parser
so that when parsing an expression, they wouldn't be recognized.
However, that now led an error field hook of the form `x: bytes
&size=42 %error` to be parsed as `&size=(42 % error)`. We now switch
to white-listing all known properties, just as we already do for
attributes. That way conflicts should be extremely rare.
  • Loading branch information
rsmmr committed Sep 24, 2024
1 parent df296c8 commit 71d0e8b
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 13 deletions.
5 changes: 3 additions & 2 deletions spicy/toolchain/src/compiler/parser/scanner.ll
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ doc_text [ \t]*##[^\n]*\n?
comment [ \t]*#[^#\n]*\n?

attribute \&(bit-order|byte-order|chunked|convert|count|cxxname|default|eod|internal|ipv4|ipv6|hilti_type|length|max-size|no-emit|nosub|on-heap|optional|originator|parse-at|parse-from|requires|responder|size|static|synchronize|transient|try|type|until|until-including|while|have_prototype)
property %(byte-order|context|cxx-include|debug|description|done|error|filter|mime-type|orig|port|random-access|resp|s_default|skip|skip-implementation|skip-post|skip-pre|spicy-version|sync-advance-block-size|synchronize-after|synchronize-at)

blank [ \t]
digit [0-9]
digits {digit}+
Expand All @@ -73,7 +75,6 @@ P ([Pp][+-]?{digits})
decfloat {digits}{E}|{digit}*\.{digits}{E}?|{digits}\.{digit}+{E}?
hexfloat 0[xX]({hexit}+{P}|{hexit}*\.{hexit}+{P}?|{hexit}+\.{hexit}+{P}?)
id [a-zA-Z_]|[a-zA-Z_][a-zA-Z_0-9]*[a-zA-Z_0-9]|[$][$]
property %[a-zA-Z_][a-zA-Z_0-9-]*
string \"(\\.|[^\\"])*\"
preprocessor @[a-zA-Z_][a-zA-Z_0-9-]*

Expand Down Expand Up @@ -231,7 +232,7 @@ Null return token::CNULL;
<NEW_KEYWORD>skip return token::SKIP;

{attribute} yylval->build(std::string(yytext)); return token::ATTRIBUTE;
<INITIAL>{property} yylval->build(std::string(yytext)); return token::PROPERTY;
{property} yylval->build(std::string(yytext)); return token::PROPERTY;
{digits}\/(tcp|udp) yylval->build(std::string(yytext)); return token::CPORT;
{address4} yylval->build(std::string(yytext)); return token::CADDRESS;
{address6} yylval->build(std::string(yytext, 1, strlen(yytext) - 2)); return token::CADDRESS;
Expand Down
17 changes: 10 additions & 7 deletions tests/Baseline/spicy.types.unit.error-hook-field/output
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,30 @@
field A standard
unit %done, [$a=b"A", $b=b"B", $c=b"C"]
---
[error] terminating with uncaught exception of type spicy::rt::ParseError: expected bytes literal "B" but input starts with "x" (<...>/error-hook-field.spicy:21:8-21:11)
[error] terminating with uncaught exception of type spicy::rt::ParseError: expected bytes literal "B" but input starts with "x" (<...>/error-hook-field.spicy:25:8-25:11)
field A standard
field B %error, attached, [$a=b"A", $b=(not set), $c=(not set)]
field B %error, external, [$a=b"A", $b=(not set), $c=(not set)]
field B %error, external, expected bytes literal "B" but input starts with "x" (<...>/error-hook-field.spicy:21:8-21:11), [$a=b"A", $b=(not set), $c=(not set)]
field B %error, external, expected bytes literal "B" but input starts with "x" (<...>/error-hook-field.spicy:25:8-25:11), [$a=b"A", $b=(not set), $c=(not set)]
field B %error, inside unit, [$a=b"A", $b=(not set), $c=(not set)]
field B %error, inside unit, expected bytes literal "B" but input starts with "x" (<...>/error-hook-field.spicy:21:8-21:11), [$a=b"A", $b=(not set), $c=(not set)]
field B %error, inside unit, expected bytes literal "B" but input starts with "x" (<...>/error-hook-field.spicy:25:8-25:11), [$a=b"A", $b=(not set), $c=(not set)]
unit %error, [$a=b"A", $b=(not set), $c=(not set)]
unit %error, external, expected bytes literal "B" but input starts with "x" (<...>/error-hook-field.spicy:21:8-21:11), [$a=b"A", $b=(not set), $c=(not set)]
unit %error, external, expected bytes literal "B" but input starts with "x" (<...>/error-hook-field.spicy:25:8-25:11), [$a=b"A", $b=(not set), $c=(not set)]
---
[error] terminating with uncaught exception of type spicy::rt::ParseError: expected bytes literal "C" but input starts with "x" (<...>/error-hook-field.spicy:22:8-22:11)
[error] terminating with uncaught exception of type spicy::rt::ParseError: expected bytes literal "C" but input starts with "x" (<...>/error-hook-field.spicy:26:8-26:11)
field A standard
unit %error, [$a=b"A", $b=b"B", $c=(not set)]
unit %error, external, [$a=b"A", $b=b"B", $c=(not set)]
unit %error, external, expected bytes literal "C" but input starts with "x" (<...>/error-hook-field.spicy:22:8-22:11), [$a=b"A", $b=b"B", $c=(not set)]
unit %error, external, expected bytes literal "C" but input starts with "x" (<...>/error-hook-field.spicy:26:8-26:11), [$a=b"A", $b=b"B", $c=(not set)]
===
---
unit %done, [$foo=[$a=b"A", $b=b"B"], $c=b"C"]
---
field A %error
unit %done, [$foo=[$a=(not set), $b=(not set)], $c=b"C"]
---
[error] terminating with uncaught exception of type spicy::rt::ParseError: expected bytes literal "B" but input starts with "x" (<...>/error-hook-field.spicy:66:8-66:11)
[error] terminating with uncaught exception of type spicy::rt::ParseError: expected bytes literal "B" but input starts with "x" (<...>/error-hook-field.spicy:69:8-69:11)
unit %error, [$foo=[$a=b"A", $b=(not set)], $c=(not set)]
===
[error] terminating with uncaught exception of type spicy::rt::ParseError: expected 5 bytes (4 bytes available) (<...>/error-hook-field.spicy:74:5-74:55)
field x %error
3 changes: 1 addition & 2 deletions tests/Baseline/spicy.types.unit.properties-fail/output
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
[warning] <...>/properties-fail.spicy:13:5-13:26: %random-access is no longer needed and deprecated
[error] <...>/properties-fail.spicy:19:3-19:13: &byte-order requires an expression
[error] <...>/properties-fail.spicy:18:3-18:13: &byte-order requires an expression
[error] <...>/properties-fail.spicy:9:5-9:10: %port requires an argument
[error] <...>/properties-fail.spicy:10:5-10:15: %port requires a port as its argument
[error] <...>/properties-fail.spicy:11:5-11:17: %description requires an argument
Expand All @@ -10,5 +10,4 @@
[error] <...>/properties-fail.spicy:15:5-15:15: %mime-type requires an argument
[error] <...>/properties-fail.spicy:16:5-16:20: %mime-type requires a string argument
[error] <...>/properties-fail.spicy:17:5-17:26: %mime-type argument must follow "main/sub" form
[error] <...>/properties-fail.spicy:18:5-18:13: unknown property '%unknown'
[error] spicyc: aborting after errors
10 changes: 9 additions & 1 deletion tests/spicy/types/unit/error-hook-field.spicy
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
# @TEST-EXEC: echo C | spicy-driver -p Mini::Test2 test.hlto 2>&1 | sort >>output
# @TEST-EXEC: echo AxC | (spicy-driver -p Mini::Test2 test.hlto 2>&1; true) | sort >>output
#
# @TEST-EXEC: echo === >>output
#
# @TEST-EXEC: echo 123 | (spicy-driver -p Mini::Test3 test.hlto 2>&1; true) | sort >>output
#
# @TEST-EXEC: btest-diff output

module Mini;
Expand All @@ -21,7 +25,6 @@ public type Test1 = unit {
b: b"B" %error { print "field B %error, attached", self; }
c: b"C";

# TODO: These don't trigger yet
on b %error {
print "field B %error, inside unit", self;
}
Expand Down Expand Up @@ -65,3 +68,8 @@ type Foo = unit {
a: b"A" %error { print "field A %error"; self.backtrack(); }
b: b"B";
};

# Test that contains a field where Bison parsing is tricky.
public type Test3 = unit {
x: bytes &size=5 %error { print "field x %error"; }
};
1 change: 0 additions & 1 deletion tests/spicy/types/unit/properties-fail.spicy
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,4 @@ public type Foo = unit {
%mime-type;
%mime-type = 42;
%mime-type = "kaputt";
%unknown;
} &byte-order;

0 comments on commit 71d0e8b

Please sign in to comment.