lang-bootstrap/06/lpeglabel/testrelabelparser.lua

550 lines
8.3 KiB
Lua
Raw Normal View History

local re = require 'relabel'
function testerror(repatt, msg)
msg = msg:match("^%s*(.-)%s*$") -- trim
local ok, err = pcall(function () re.compile(repatt) end)
assert(not ok)
if msg:match("^[^\n]*\n(.-)$") then
-- expecting a syntax error
err = err:match("^[^\n]*\n(.-)$") -- remove first line (filename)
err = err:gsub("[ \t]*\n", "\n") -- remove trailing spaces
-- if err ~= msg then
-- print(#err, #msg)
-- print('--')
-- print(err)
-- print('--')
-- print(msg)
-- print('--')
-- end
assert(err == msg)
else
-- expecting a non-syntax error
assert(err:match(msg))
end
end
-- testing NoPatt
testerror([[~]], [[
L1:C1: no pattern found
~
^
]])
testerror([[???]], [[
L1:C1: no pattern found
???
^
]])
-- testing ExtraChars
testerror([['p'~]], [[
L1:C4: unexpected characters after the pattern
'p'~
^
]])
testerror([['p'?$?]], [[
L1:C5: unexpected characters after the pattern
'p'?$?
^
]])
-- testing ExpPatt1
testerror([['p' //{1}]], [[
L1:C10: expected a pattern after '/' or '//{...}'
'p' //{1}
^
]])
testerror([['p' //{1} //{2} 'q']], [[
L1:C10: expected a pattern after '/' or '//{...}'
'p' //{1} //{2} 'q'
^
]])
testerror([['p' /]], [[
L1:C6: expected a pattern after '/' or '//{...}'
'p' /
^
]])
testerror([['p' / / 'q']], [[
L1:C6: expected a pattern after '/' or '//{...}'
'p' / / 'q'
^
]])
-- testing ExpPatt2
testerror([[&]], [[
L1:C2: expected a pattern after '&'
&
^
]])
testerror([[& / 'p']], [[
L1:C2: expected a pattern after '&'
& / 'p'
^
]])
testerror([['p' &]], [[
L1:C6: expected a pattern after '&'
'p' &
^
]])
testerror([['p' / & / 'q']], [[
L1:C8: expected a pattern after '&'
'p' / & / 'q'
^
]])
testerror([[&&]], [[
L1:C3: expected a pattern after '&'
&&
^
]])
testerror([[!&]], [[
L1:C3: expected a pattern after '&'
!&
^
]])
-- testing ExpPatt3
testerror([[!]], [[
L1:C2: expected a pattern after '!'
!
^
]])
testerror([[! / 'p']], [[
L1:C2: expected a pattern after '!'
! / 'p'
^
]])
testerror([['p' !]], [[
L1:C6: expected a pattern after '!'
'p' !
^
]])
testerror([['p' / ! / 'q']], [[
L1:C8: expected a pattern after '!'
'p' / ! / 'q'
^
]])
testerror([[!!]], [[
L1:C3: expected a pattern after '!'
!!
^
]])
testerror([[&!]], [[
L1:C3: expected a pattern after '!'
&!
^
]])
-- testing ExpPatt4
testerror([[()]], [[
L1:C2: expected a pattern after '('
()
^
]])
testerror([[($$$)]], [[
L1:C2: expected a pattern after '('
($$$)
^
]])
-- testing ExpPatt5
testerror([[{: *** :}]], [[
L1:C3: expected a pattern after ':'
{: *** :}
^
]])
testerror([[{:group: *** :}]], [[
L1:C9: expected a pattern after ':'
{:group: *** :}
^
]])
testerror([[x <- {:x:}]], [[
L1:C10: expected a pattern after ':'
x <- {:x:}
^
]])
-- testing ExpPatt6
testerror([[{~~}]], [[
L1:C3: expected a pattern after '{~'
{~~}
^
]])
testerror([[{ {~ } ~}]], [[
L1:C5: expected a pattern after '{~'
{ {~ } ~}
^
]])
testerror([[{~ ^_^ ~}]], [[
L1:C3: expected a pattern after '{~'
{~ ^_^ ~}
^
]])
-- testing ExpPatt7
testerror([[{||}]], [[
L1:C3: expected a pattern after '{|'
{||}
^
]])
testerror([[{|@|}]], [[
L1:C3: expected a pattern after '{|'
{|@|}
^
]])
-- testing ExpPatt8
testerror([[S <-]], [[
L1:C5: expected a pattern after '<-'
S <-
^
]])
testerror([[S <- 'p' T <-]], [[
L1:C14: expected a pattern after '<-'
S <- 'p' T <-
^
]])
-- testing ExpPattOrClose
testerror([[{0}]], [[
L1:C2: expected a pattern or closing '}' after '{'
{0}
^
]])
testerror([[{ :'p': }]], [[
L1:C2: expected a pattern or closing '}' after '{'
{ :'p': }
^
]])
-- testing ExpNum
testerror([['p' ^ n]], [[
L1:C6: expected a number after '^', '+' or '-' (no space)
'p' ^ n
^
]])
testerror([['p'^+(+1)]], [[
L1:C5: expected a number after '^', '+' or '-' (no space)
'p'^+(+1)
^
]])
testerror([['p'^-/'q']], [[
L1:C5: expected a number after '^', '+' or '-' (no space)
'p'^-/'q'
^
]])
-- testing ExpCap
testerror([['p' -> {]], [[
L1:C7: expected a string, number, '{}' or name after '->'
'p' -> {
^
]])
testerror([['p' -> {'q'}]], [[
L1:C7: expected a string, number, '{}' or name after '->'
'p' -> {'q'}
^
]])
testerror([['p' -> / 'q']], [[
L1:C7: expected a string, number, '{}' or name after '->'
'p' -> / 'q'
^
]])
testerror([['p' -> [0-9] ]], [[
L1:C7: expected a string, number, '{}' or name after '->'
'p' -> [0-9]
^
]])
-- testing ExpName1
testerror([['p' =>]], [[
L1:C7: expected the name of a rule after '=>'
'p' =>
^
]])
testerror([['p' => 'q']], [[
L1:C7: expected the name of a rule after '=>'
'p' => 'q'
^
]])
-- testing ExpName2
testerror([['<' {:tag: [a-z]+ :} '>' '<' = '>']], [[
L1:C31: expected the name of a rule after '=' (no space)
'<' {:tag: [a-z]+ :} '>' '<' = '>'
^
]])
testerror([['<' {:tag: [a-z]+ :} '>' '<' = tag '>']], [[
L1:C31: expected the name of a rule after '=' (no space)
'<' {:tag: [a-z]+ :} '>' '<' = tag '>'
^
]])
-- testing ExpName3
testerror([[<>]], [[
L1:C2: expected the name of a rule after '<' (no space)
<>
^
]])
testerror([[<123>]], [[
L1:C2: expected the name of a rule after '<' (no space)
<123>
^
]])
testerror([[< hello >]], [[
L1:C2: expected the name of a rule after '<' (no space)
< hello >
^
]])
testerror([[<<S>>]], [[
L1:C2: expected the name of a rule after '<' (no space)
<<S>>
^
]])
-- testing ExpLab1
testerror([['p' //{} 'q']], [[
L1:C8: expected at least one label after '{'
'p' //{} 'q'
^
]])
testerror([[%{ 'label' }]], [[
L1:C3: expected at least one label after '{'
%{ 'label' }
^
]])
-- testing ExpLab2
testerror([['p' //{1,2,3,} 'q']], [[
L1:C14: expected a label after the comma
'p' //{1,2,3,} 'q'
^
]])
-- testing ExpNameOrLab
testerror([[% s]], [[
L1:C2: expected a name or label after '%' (no space)
% s
^
]])
testerror([[% {1}]], [[
L1:C2: expected a name or label after '%' (no space)
% {1}
^
]])
-- testing ExpItem
testerror([[
"p" [
abc
] "q"
]], [[
L1:C6: expected at least one item after '[' or '^'
"p" [
^
]])
-- testing MisClose1
testerror([[('p' ('q' / 'r')]], [[
L1:C17: missing closing ')'
('p' ('q' / 'r')
^
]])
-- testing MisClose2
-- two errors are reported due to the ignore strategy
testerror([[{: group: 'p' :}]], [[
L1:C9: missing closing ':}'
{: group: 'p' :}
^
]])
testerror([[S <- {: 'p' T <- 'q']], [[
L1:C12: missing closing ':}'
S <- {: 'p' T <- 'q'
^
]])
-- testing MisClose3
testerror([['p' {~ ('q' 'r') / 's']], [[
L1:C23: missing closing '~}'
'p' {~ ('q' 'r') / 's'
^
]])
-- testing MisClose4
-- two errors are reported due to the ignore strategy
testerror([['p' {| 'q' / 'r' }]], [[
L1:C17: missing closing '|}'
'p' {| 'q' / 'r' }
^
]])
-- testing MisClose5
testerror([[{ 'p' ]], [[
L1:C6: missing closing '}'
{ 'p'
^
]])
-- testing MisClose6
testerror([[<patt]], [[
L1:C6: missing closing '>'
<patt
^
]])
testerror([[<insert your name here>]], [[
L1:C8: missing closing '>'
<insert your name here>
^
]])
-- testing MisClose7
testerror([['{' %{ a, b '}']], [[
L1:C9: missing closing '}'
'{' %{ a, b '}'
^
]])
-- testing MisClose8
testerror([[[]], [[
L1:C2: missing closing ']'
[
^
]])
testerror([[[^]], [[
L1:C3: missing closing ']'
[^
^
]])
testerror([[[] ]], [[
L1:C4: missing closing ']'
[]
^
]])
testerror([[[^] ]], [[
L1:C6: missing closing ']'
[^]
^
]])
testerror([[[_-___-_|]], [[
L1:C10: missing closing ']'
[_-___-_|
^
]])
-- testing MisTerm1
testerror([['That is the question...]], [[
L1:C25: missing terminating single quote
'That is the question...
^
]])
-- testing MisTerm2
testerror([[Q <- "To be or not to be...]], [[
L1:C28: missing terminating double quote
Q <- "To be or not to be...
^
]])
-- testing non-syntax errors
testerror([[
A <- %nosuch %def
A <- 'A again'
A <- 'and again'
]], [[
name 'nosuch' undefined
]])
testerror([[names not in grammar]], [[
rule 'names' used outside a grammar
]])
testerror([[
A <- %nosuch %def
A <- 'A again'
A <- 'and again'
]], [[
name 'nosuch' undefined
]])
-- the non-syntax error should not be reported
-- since there is a syntax error
testerror([[ A <- %nosuch ('error' ]], [[
L1:C23: missing closing ')'
A <- %nosuch ('error'
^
]])
print 'OK'