From 8311023ddc811a7c404e13df78ffc4c5aaf2410e Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Sat, 3 Jun 2023 10:51:42 -0700 Subject: [PATCH 1/5] Fix line folding on alt in HTML. --- etc/turtle.html | 141 +++++++++++++++++++++++---------------------- lib/ebnf/writer.rb | 12 ++-- 2 files changed, 77 insertions(+), 76 deletions(-) diff --git a/etc/turtle.html b/etc/turtle.html index 9cebd1f..4c86e53 100644 --- a/etc/turtle.html +++ b/etc/turtle.html @@ -1,23 +1,24 @@ + - + - + - + @@ -47,31 +48,31 @@ - + - + - + - + - + @@ -83,13 +84,13 @@ - + - + @@ -101,49 +102,49 @@ - + - + - + - + - + - + - + - + @@ -154,13 +155,13 @@ - + - + @@ -172,198 +173,198 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + - + - + - + - + @@ -375,13 +376,13 @@ - + - +
[1] turtleDoc ::=statement*statement*
[2] statement ::=directive | (triples ".")directive | (triples ".")
[3] directive ::=prefixID | base | sparqlPrefix | sparqlBaseprefixID | base | sparqlPrefix | sparqlBase
[4][6] triples ::=(subject predicateObjectList) | (blankNodePropertyList predicateObjectList?)(subject predicateObjectList) | (blankNodePropertyList predicateObjectList?)
[7] predicateObjectList ::=verb objectList (";" (verb objectList)?)*verb objectList (";" (verb objectList)?)*
[8] objectList ::=object ("," object)*object ("," object)*
[9] verb ::=predicate | "a"predicate | "a"
[10] subject ::=iri | BlankNode | collectioniri | BlankNode | collection
[11][12] object ::=iri | BlankNode | collection | blankNodePropertyList | literaliri | BlankNode | collection | blankNodePropertyList | literal
[13] literal ::=RDFLiteral | NumericLiteral | BooleanLiteralRDFLiteral | NumericLiteral | BooleanLiteral
[14][15] collection ::="(" object* ")""(" object* ")"
[16] NumericLiteral ::=INTEGER | DECIMAL | DOUBLEINTEGER | DECIMAL | DOUBLE
[128s] RDFLiteral ::=String (LANGTAG | ("^^" iri))?String (LANGTAG | ("^^" iri))?
[133s] BooleanLiteral ::="true" | "false""true" | "false"
[17] String ::=STRING_LITERAL_QUOTE | STRING_LITERAL_SINGLE_QUOTE | STRING_LITERAL_LONG_SINGLE_QUOTE | STRING_LITERAL_LONG_QUOTESTRING_LITERAL_QUOTE | STRING_LITERAL_SINGLE_QUOTE | STRING_LITERAL_LONG_SINGLE_QUOTE | STRING_LITERAL_LONG_QUOTE
[135s] iri ::=IRIREF | PrefixedNameIRIREF | PrefixedName
[136s] PrefixedName ::=PNAME_LN | PNAME_NSPNAME_LN | PNAME_NS
[137s] BlankNode ::=BLANK_NODE_LABEL | ANONBLANK_NODE_LABEL | ANON
@terminals[18] IRIREF ::="<" ([^<>"{}|^`]-[#x00-#x20] | UCHAR)* ">""<" (([^<>"{}|^`\] - [#x00-#x20]) | UCHAR)* ">"
[139s] PNAME_NS ::=PN_PREFIX? ":"PN_PREFIX? ":"
[140s][141s] BLANK_NODE_LABEL ::="_:" (PN_CHARS_U | [0-9]) ((PN_CHARS | ".")* PN_CHARS)?"_:" (PN_CHARS_U | [0-9]) ((PN_CHARS | ".")* PN_CHARS)?
[144s] LANGTAG ::="@" [a-zA-Z]+ ("-" [a-zA-Z0-9]+)*"@" [a-zA-Z]+ ("-" [a-zA-Z0-9]+)*
[19] INTEGER ::=[+-]? [0-9]+[+-]? [0-9]+
[20] DECIMAL ::=[+-]? ([0-9]* "." [0-9]+)[+-]? ([0-9]* "." [0-9]+)
[21] DOUBLE ::=[+-]? (([0-9]+ "." [0-9]* EXPONENT) | ("." [0-9]+ EXPONENT) | ([0-9]+ EXPONENT))[+-]? (([0-9]+ "." [0-9]* EXPONENT) | ("." [0-9]+ EXPONENT) | ([0-9]+ EXPONENT))
[154s] EXPONENT ::=[eE] [+-]? [0-9]+[eE] [+-]? [0-9]+
[22] STRING_LITERAL_QUOTE ::='"' ([^>"#x5C#x0A#x0D] | ECHAR | UCHAR)* '"''"' ([^>"#x5C#x0A#x0D] | ECHAR | UCHAR)* '"'
[23] STRING_LITERAL_SINGLE_QUOTE ::="'" ([^#x27#x5C#x0A#x0D] | ECHAR | UCHAR)* "'""'" ([^#x27#x5C#x0A#x0D] | ECHAR | UCHAR)* "'"
[24] STRING_LITERAL_LONG_SINGLE_QUOTE ::="'''" (("'" | "''")? [^']#x20|#x20ECHAR#x20|#x20UCHAR#x20)#x20)*#x20"'''"])"'''" (("'" | "''")? ([^'\] | ECHAR | UCHAR))* "'''"
[25] STRING_LITERAL_LONG_QUOTE ::='"""' (('"' | '""')? [^"]#x20|#x20ECHAR#x20|#x20UCHAR#x20)#x20)*#x20'"""'])'"""' (('"' | '""')? ([^"\] | ECHAR | UCHAR))* '"""'
[26] UCHAR ::=("u" HEX HEX HEX HEX) | ("U" HEX HEX HEX HEX HEX HEX HEX HEX)("u" HEX HEX HEX HEX) | ("U" HEX HEX HEX HEX HEX HEX HEX HEX)
[159s] ECHAR ::="\" [tbnrf"']"\" [tbnrf"']
[28t] SPARQL_PREFIX ::=[Pp] [Rr] [Ee] [Ff] [Ii] [Xx][Pp] [Rr] [Ee] [Ff] [Ii] [Xx]
[29t] SPARQL_BASE ::=[Bb] [Aa] [Ss] [Ee][Bb] [Aa] [Ss] [Ee]
[161s] WS ::=#x20 | #x09 | #x0D | #x0A#x20 | #x09 | #x0D | #x0A
[162s] ANON ::="[" WS* "]""[" WS* "]"
[163s] PN_CHARS_BASE ::=[A-Z][A-Z]
|[a-z]|[a-z]
|[#xC0-#xD6]|[#xC0-#xD6]
|[#xD8-#xF6]|[#xD8-#xF6]
|[#xF8-#x02FF]|[#xF8-#x02FF]
|[#x0370-#x037D]|[#x0370-#x037D]
|[#x037F-#x1FFF]|[#x037F-#x1FFF]
|[#x200C-#x200D]|[#x200C-#x200D]
|[#x2070-#x218F]|[#x2070-#x218F]
|[#x2C00-#x2FEF]|[#x2C00-#x2FEF]
|[#x3001-#xD7FF]|[#x3001-#xD7FF]
|[#xF900-#xFDCF]|[#xF900-#xFDCF]
|[#xFDF0-#xFFFD]|[#xFDF0-#xFFFD]
|[#x00010000-#x000EFFFF]|[#x00010000-#x000EFFFF]
[164s] PN_CHARS_U ::=PN_CHARS_BASE | "_"PN_CHARS_BASE | "_"
[166s] PN_CHARS ::=PN_CHARS_U | "-" | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]PN_CHARS_U | "-" | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]
[167s] PN_PREFIX ::=PN_CHARS_BASE ((PN_CHARS | ".")* PN_CHARS)?PN_CHARS_BASE ((PN_CHARS | ".")* PN_CHARS)?
[168s] PN_LOCAL ::=(PN_CHARS_U | ":" | [0-9] | PLX) ((PN_CHARS | "." | ":" | PLX)* (PN_CHARS | ":" | PLX))?(PN_CHARS_U | ":" | [0-9] | PLX) ((PN_CHARS | "." | ":" | PLX)* (PN_CHARS | ":" | PLX))?
[169s] PLX ::=PERCENT | PN_LOCAL_ESCPERCENT | PN_LOCAL_ESC
[170s][171s] HEX ::=[0-9A-Fa-f][0-9A-Fa-f]
[172s] PN_LOCAL_ESC ::="\" ("_" | "~" | "." | "-" | "!" | "$" | "&" | "'" | "(" | ")" | "*" | "+" | "," | ";" | "=" | "/" | "?" | "#" | "@" | "%")"\" ("_" | "~" | "." | "-" | "!" | "$" | "&" | "'" | "(" | ")" | "*" | "+" | "," | ";" | "=" | "/" | "?" | "#" | "@" | "%")
diff --git a/lib/ebnf/writer.rb b/lib/ebnf/writer.rb index e7b28df..2656949 100644 --- a/lib/ebnf/writer.rb +++ b/lib/ebnf/writer.rb @@ -150,14 +150,14 @@ def initialize(rules, out: $stdout, html: false, format: :ebnf, validate: false, split(/\s*--rule-extensions--\s*/).each_with_index do |formatted, ndx| assign = case format when :ebnf - formatted.sub!(%r{\s*\|\s*}, '') - (ndx > 0 ? (rule.alt? ? '|' : '') : '::=') + formatted.sub!(%r{\s*]*>\|\s*}, '') + (ndx > 0 ? (rule.alt? ? '|' : '') : '::=') when :abnf - formatted.sub!(%r{\s*/\s*}, '') - (ndx > 0 ? '=/' : '=') + formatted.sub!(%r{\s*]>/\s*}, '') + (ndx > 0 ? '=/' : '=') else - formatted.sub!(%r{\s*\|\s*}, '') - (ndx > 0 ? (rule.alt? ? '|' : '') : '=') + formatted.sub!(%r{\s*]>\|\s*}, '') + (ndx > 0 ? (rule.alt? ? '|' : '') : '=') end lines << OpenStruct.new(id: ((ndx == 0 ? "[#{rule.id}]" : "") if rule.id), sym: (rule.sym if ndx == 0 || format == :abnf), From 344972f162eafe7c78975a7df4b43de63d94e29b Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Sat, 3 Jun 2023 15:30:36 -0700 Subject: [PATCH 2/5] Mark other EBNF strings using grammar-literal in HTML output. --- etc/turtle.html | 14 +++++++------- lib/ebnf/writer.rb | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/etc/turtle.html b/etc/turtle.html index 4c86e53..a9f59ea 100644 --- a/etc/turtle.html +++ b/etc/turtle.html @@ -24,13 +24,13 @@ [4] prefixID ::= - "@prefix" PNAME_NS IRIREF "." + "@prefix" PNAME_NS IRIREF "." [5] base ::= - "@base" IRIREF "." + "@base" IRIREF "." [28s] @@ -114,13 +114,13 @@ [128s] RDFLiteral ::= - String (LANGTAG | ("^^" iri))? + String (LANGTAG | ("^^" iri))? [133s] BooleanLiteral ::= - "true" | "false" + "true" | "false" [17] @@ -173,7 +173,7 @@ [141s] BLANK_NODE_LABEL ::= - "_:" (PN_CHARS_U | [0-9]) ((PN_CHARS | ".")* PN_CHARS)? + "_:" (PN_CHARS_U | [0-9]) ((PN_CHARS | ".")* PN_CHARS)? [144s] @@ -221,13 +221,13 @@ [24] STRING_LITERAL_LONG_SINGLE_QUOTE ::= - "'''" (("'" | "''")? ([^'\] | ECHAR | UCHAR))* "'''" + "'''" (("'" | "''")? ([^'\] | ECHAR | UCHAR))* "'''" [25] STRING_LITERAL_LONG_QUOTE ::= - '"""' (('"' | '""')? ([^"\] | ECHAR | UCHAR))* '"""' + '"""' (('"' | '""')? ([^"\] | ECHAR | UCHAR))* '"""' [26] diff --git a/lib/ebnf/writer.rb b/lib/ebnf/writer.rb index 2656949..edbd955 100644 --- a/lib/ebnf/writer.rb +++ b/lib/ebnf/writer.rb @@ -351,8 +351,8 @@ def format_ebnf_string(string, quote = '"') end end - res = "#{quote}#{string}#{quote}" - @options[:html] ? @coder.encode(res) : res + res = @options[:html] ? %(#{@coder.encode(string)}) : string + res = "#{quote}#{res}#{quote}" end def escape_ebnf_hex(u) From 5691702f9ae1f47b2cb04910cf7083d98782b237 Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Fri, 9 Jun 2023 17:02:20 -0700 Subject: [PATCH 3/5] Mark declarations in HTML output with a class to allow CSS targeting. --- etc/turtle.html | 158 ++++++++++++++---------------------------- lib/ebnf/ll1/lexer.rb | 2 +- lib/ebnf/writer.rb | 14 ++-- 3 files changed, 62 insertions(+), 112 deletions(-) diff --git a/etc/turtle.html b/etc/turtle.html index a9f59ea..4d4bf5b 100644 --- a/etc/turtle.html +++ b/etc/turtle.html @@ -2,272 +2,228 @@ - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - - + + - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - @@ -336,51 +292,43 @@ - + - - + - - + - - + - - + - - + - - + - - + - diff --git a/lib/ebnf/ll1/lexer.rb b/lib/ebnf/ll1/lexer.rb index 3aa8a73..7501a6f 100644 --- a/lib/ebnf/ll1/lexer.rb +++ b/lib/ebnf/ll1/lexer.rb @@ -201,7 +201,7 @@ def shift # @param [Array[Symbol]] types Optional set of types for restricting terminals examined # @return [Token] def recover(*types) - until scanner.eos? || tok = match_token(*types) + until scanner.eos? || tok = match_token(*types) if scanner.skip_until(@whitespace || /\s+/m).nil? # Skip past current "token" # No whitespace at the end, must be and end of string scanner.terminate diff --git a/lib/ebnf/writer.rb b/lib/ebnf/writer.rb index edbd955..8b35631 100644 --- a/lib/ebnf/writer.rb +++ b/lib/ebnf/writer.rb @@ -133,7 +133,8 @@ def initialize(rules, out: $stdout, html: false, format: :ebnf, validate: false, formatted_rules = rules.map do |rule| if rule.kind == :terminals || rule.kind == :pass OpenStruct.new(id: ("@#{rule.kind}"), - sym: nil, + class: :declaration, + sym: rule.kind, assign: nil, formatted: ( rule.kind == :terminals ? @@ -161,6 +162,7 @@ def initialize(rules, out: $stdout, html: false, format: :ebnf, validate: false, end lines << OpenStruct.new(id: ((ndx == 0 ? "[#{rule.id}]" : "") if rule.id), sym: (rule.sym if ndx == 0 || format == :abnf), + class: :production, assign: assign, formatted: formatted) end @@ -170,6 +172,7 @@ def initialize(rules, out: $stdout, html: false, format: :ebnf, validate: false, lines else OpenStruct.new(id: ("[#{rule.id}]" if rule.id), + class: :production, sym: rule.sym, assign: (format == :ebnf ? '::=' : '='), formatted: (formatted_expr + (format == :isoebnf ? ' ;' : ''))) @@ -708,17 +711,16 @@ def format_isoebnf_range(string) chars.length == 1 ? chars.last.inspect : chars.unshift(:alt) end - ERB_DESC = %q( - -
[1]turtleDoc ::= statement*
[2]statement ::= directive | (triples ".")
[3]directive ::= prefixID | base | sparqlPrefix | sparqlBase
[4]prefixID ::= "@prefix" PNAME_NS IRIREF "."
[5]base ::= "@base" IRIREF "."
[28s]sparqlPrefix ::= SPARQL_PREFIX PNAME_NS IRIREF
[29s]sparqlBase ::= SPARQL_BASE IRIREF
[6]triples ::= (subject predicateObjectList) | (blankNodePropertyList predicateObjectList?)
[7]predicateObjectList ::= verb objectList (";" (verb objectList)?)*
[8]objectList ::= object ("," object)*
[9]verb ::= predicate | "a"
[10]subject ::= iri | BlankNode | collection
[11]predicate ::= iri
[12]object ::= iri | BlankNode | collection | blankNodePropertyList | literal
[13]literal ::= RDFLiteral | NumericLiteral | BooleanLiteral
[14]blankNodePropertyList ::= "[" predicateObjectList "]"
[15]collection ::= "(" object* ")"
[16]NumericLiteral ::= INTEGER | DECIMAL | DOUBLE
[128s]RDFLiteral ::= String (LANGTAG | ("^^" iri))?
[133s]BooleanLiteral ::= "true" | "false"
[17]String ::= STRING_LITERAL_QUOTE | STRING_LITERAL_SINGLE_QUOTE | STRING_LITERAL_LONG_SINGLE_QUOTE | STRING_LITERAL_LONG_QUOTE
[135s]iri ::= IRIREF | PrefixedName
[136s]PrefixedName ::= PNAME_LN | PNAME_NS
[137s]BlankNode ::= BLANK_NODE_LABEL | ANON
@terminals
@terminals # Productions for terminals
[18]IRIREF ::= "<" (([^<>"{}|^`\] - [#x00-#x20]) | UCHAR)* ">"
[139s]PNAME_NS ::= PN_PREFIX? ":"
[140s]PNAME_LN ::= PNAME_NS PN_LOCAL
[141s]BLANK_NODE_LABEL ::= "_:" (PN_CHARS_U | [0-9]) ((PN_CHARS | ".")* PN_CHARS)?
[144s]LANGTAG ::= "@" [a-zA-Z]+ ("-" [a-zA-Z0-9]+)*
[19]INTEGER ::= [+-]? [0-9]+
[20]DECIMAL ::= [+-]? ([0-9]* "." [0-9]+)
[21]DOUBLE ::= [+-]? (([0-9]+ "." [0-9]* EXPONENT) | ("." [0-9]+ EXPONENT) | ([0-9]+ EXPONENT))
[154s]EXPONENT ::= [eE] [+-]? [0-9]+
[22]STRING_LITERAL_QUOTE ::= '"' ([^>"#x5C#x0A#x0D] | ECHAR | UCHAR)* '"'
[23]STRING_LITERAL_SINGLE_QUOTE ::= "'" ([^#x27#x5C#x0A#x0D] | ECHAR | UCHAR)* "'"
[24]STRING_LITERAL_LONG_SINGLE_QUOTE ::= "'''" (("'" | "''")? ([^'\] | ECHAR | UCHAR))* "'''"
[25]STRING_LITERAL_LONG_QUOTE ::= '"""' (('"' | '""')? ([^"\] | ECHAR | UCHAR))* '"""'
[26]UCHAR ::= ("u" HEX HEX HEX HEX) | ("U" HEX HEX HEX HEX HEX HEX HEX HEX)
[159s]ECHAR ::= "\" [tbnrf"']
[28t]SPARQL_PREFIX ::= [Pp] [Rr] [Ee] [Ff] [Ii] [Xx]
[29t]SPARQL_BASE ::= [Bb] [Aa] [Ss] [Ee]
[161s]WS ::= #x20 | #x09 | #x0D | #x0A
[162s]ANON ::= "[" WS* "]"
[163s]PN_CHARS_BASE ::= [A-Z]
| [#x00010000-#x000EFFFF]
[164s]PN_CHARS_U ::= PN_CHARS_BASE | "_"
[166s]PN_CHARS ::= PN_CHARS_U | "-" | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]
[167s]PN_PREFIX ::= PN_CHARS_BASE ((PN_CHARS | ".")* PN_CHARS)?
[168s]PN_LOCAL ::= (PN_CHARS_U | ":" | [0-9] | PLX) ((PN_CHARS | "." | ":" | PLX)* (PN_CHARS | ":" | PLX))?
[169s]PLX ::= PERCENT | PN_LOCAL_ESC
[170s]PERCENT ::= "%" HEX HEX
[171s]HEX ::= [0-9A-Fa-f]
[172s]PN_LOCAL_ESC ::= "\" ("_" | "~" | "." | "-" | "!" | "$" | "&" | "'" | "(" | ")" | "*" | "+" | "," | ";" | "=" | "/" | "?" | "#" | "@" | "%")
+ ERB_DESC = %(\n) + + %q(
<% for rule in @rules %> - > + > <% if rule.id %> ><%= rule.id %> <% end %> <% if rule.sym %> - + <% end %> From 609ec582a190f57579b61b96fceee15506c47a72 Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Fri, 9 Jun 2023 17:31:57 -0700 Subject: [PATCH 4/5] Fix issue with OpenStruct in Ruby <= 2.7. --- lib/ebnf/writer.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ebnf/writer.rb b/lib/ebnf/writer.rb index 8b35631..b5ab6b8 100644 --- a/lib/ebnf/writer.rb +++ b/lib/ebnf/writer.rb @@ -715,7 +715,7 @@ def format_isoebnf_range(string) %q(
<%== rule.sym %><%== (rule.sym unless rule.class == :declaration) %><%= rule.assign %> <%= rule.formatted %>
<% for rule in @rules %> - > + > <% if rule.id %> ><%= rule.id %> <% end %> From 7bda2efb902b56083092bda37ae09c3049c0458c Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Fri, 9 Jun 2023 17:18:33 -0700 Subject: [PATCH 5/5] Version 3.2.4. --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 0bee604..3f684d2 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.3.3 +2.3.4