Newbie questions about Pliant

Newbie questions about Pliant

Verbatim Multiline Strings

The parser_filter_newline function assumes indentation
Message posted by maybe Boris Reitman on 2003/12/30 22:23:10
Here's what I would like to be parsed correctly,

  #...
  if true
    console "Movie quote:" 
    console {{    
    Agent 007
  ------------- 
My name is Bond. 
}} eol
    console "James Bond." eol
  else
    console "So long" eol

The string to go inside the special double braces
will be perl code, which is not structured
around indentation.

The problem arises when parser_filter_newline is
executed on the "if true" statement.  It will
try to find the end of block and will incorrectly
decide that the block ends at the line before 
"---------" and will register a pending 
function 'pending_close_block' to occur right after "007".
The correct thing is to have it occur just before 
the "else" statement.

So how can I approach this ? Should I adjust all the 
threshold (x,y) coordinates inside the pending queue 
when I'm inside my custom filter attached to "{{" token ?
Doesn't seem to be scalable.

My work in progress code can be seen here,

  http://lougheed.boris.reitman.info:8165/pliant-perl/pliantx/lexer/multiline_string.html

I'm temporarily clearing the pending queque and restore when I'm done.
Here is the sample run,

$ cat -n test.pli 
     1 module "/pliantx/lexer/multiline_string.pli"
     2 #console {{ xxx }} eol
     3 console {{ hello
     4 bye
     5 BYE
     6 }}
$ pliant test.pli 
here
here
here
New string token: " hello
bye
BYE
"
Next will look at: ''
parser_pending_close_instruction
pending x = 0
pending y = 3
console y = 5
original y = 3
------
new pending x = 0
new pending y = 5
 hello
bye
BYE
----------------------------------------------------------------
Failed to compile bye   ()
  compile file:test.pli (internals) 7 1
compile file:test.pli (internals) 7 1
compile file:test.pli (internals) 7 1
parse file:test.pli (internals) 8 1
module file:test.pli
----------------------------------------------------------------
actions stack is:
parse file:test.pli (internals) 8 1
module file:test.pli
----------------------------------------------------------------
processor stack content is:
error_notify_fatal (ErrorID Str) +14
error_report +61
error_renotify (ErrorID Address Str) +41
. compile (Expression) +125
  file:test.pli (internals) 7 1
parser_tag_record  /pliant/language/type/misc/tag.pli (internals) 182 1
. execute (ParserContext) +39
parser_filter_execute +240
pliant internal parse_one_token function (ParserContext) +391
compile_text (List Module) +230
pliant_load_module (Str Module Int Module) +920
??? at 134599668
----------------------------------------------------------------

I wonder why is it looking at the 'bye' line, the
context:y and context:current_line are way past it.

Can filter the text when its being read from file ? (i.e. before any other 
filter )  I will just rewrite the multiline strings to be single line,
and that will be a scalable solution. If this is possible, how do I do it ?



Message posted by hubert.tonneau on 2003/12/30 23:22:37
Anything that breaks indentation rule is not compatible with existing Pliant syntax.
If you want to allow such things, the syntax will not mixte properly with other
parts of the code using Pliant default syntax in the same module.
The reason is that the indentation engine is fairly naive, so must not be
disturbed.

The best solution might be to have a kind of pre processor, but then we fall on
another problem: the syntax is changing according to 'module', which is currently
parsed standardly, so the preprocessor would probably require to detect 'module'
with a more rigid way. the drawback would be that it would not allow anymore
nice things like:

constant alternative false

if alternative
  module "mymodule.pli"

As an alternative, you can study the 'parser_filter_newline' function (which
is handling indentation) in module /pliant/language/parser/buildin.c and suggest
improvements in order to make it more flexible, yet keep it resonably simple.
Message posted by maybe Boris Reitman on 2003/12/30 23:57:50
I don't understand why it would be a problem to add a preprocessor
function to filter a text stream as it is being read from disk.
For example the file can be zipped,

  function unzip_preprocessor in -> out
    arg Stream in out
    # ...

  register_preprocessor unzip_preprocessor ".pli.gz"
  module "locale_fr.pli.gz"

The locale_fr.pli.gz is automatically uncompressed.
Message posted by hubert.tonneau on 2003/12/31 00:00:59
So you implicitely mean that there should be a file extension -> module
mapping, so that when a new module is loaded, a first module is included
according to it's file extension before starting to load parse execute.
Message posted by maybe Boris Reitman on 2003/12/31 00:35:11
I thought that the modules are loaded in a particular fixed order.
As long as the correct pipe of preprocessors has been registered 
 for some file extension by some previous modules, the module 
statement will be performed correctly.  I'm not sure how include 
cycles are handled.  This is the same dependancy system as with 'meta'
code.

 



Message posted by maybe Boris Reitman on 2003/12/31 00:43:15
I reread your message.  Yes this is what I meant,
preprocess file by extension before lexing it.
Message posted by hubert.tonneau on 2003/12/31 01:02:00
So, what we need is a general dictionary, so that when loading a new module,
we search for the extension, and if we find a function we call it so that it
can change the listing before real parsing starts.
Message posted by maybe Boris Reitman on 2003/12/31 01:30:55
Yes, that sounds good.  The user should be able to extend
the current preprocessor associated with a particular 
-- wrapping functions in other functions is probably ok.
Or we can use a list of functions as the values in the
dictionary. 
Message posted by maybe Boris Reitman on 2003/12/31 20:49:45
Hi,

I thought about it some more.  There must be easy way to extend the
current preprossesor and also this extension should not be global
accross all code, but specific to module scope.  The preprocessor that is
aware about filename type (filename extension or mime/type) should be the 
first one in the chain of preprocessors.  Its implementation will involve
looking up in the dictionary of handlers, as you have suggested.
But for my verbatim string implementation I would like to wrap its output,
which will be extracted pliant code.  Only modules that include my module
will be parsed according to my preprossesor extension.

# test.pli
module "/pliantx/lexer/multiline_string.pli"
# post: this module 'exported' a new preprossesor that affects all
# code below

console {{
  Happy
  New
  Year!
}} eol