lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


KHMan wrote:
<heavy snippage>
Yueliang is a casual project with no clear goals, so it's in bits
and pieces. You can follow what the bits and pieces are by looking
at what the test scripts use.

test_lparser_mk3.lua in the test directory exercises the
lparser_mk3.lua parser, and uses the llex_mk3.lua lexer as well.
The parser_log directory shows the result of the message logger
calls, basically showing which functions are called during
parsing, and it closely follows the original C equivalents.
OK, I took a second longer glance and armed with your advice on which bits of files to look into figured it all out. YOur naming in the comment about example usage, talking about x and y, was what made it difficult for me. Variable names do matter, especially if reading out with speech. I really like code that sounds good spoken e.g:
if not ready then return end

I've now discovered the very basic usage. Given a function to print tables recursively, such as:

function dump(data)
  for key, value in pairs(data) do
     if type(value) == "table" then
        print("Begin table", key, ":")
        dump(value)
        print("end table", key, ".")
     else
        print(key, "is", value)
end end end -- if, for, function

One can look at what the parser logs for a piece of code by doing something like this, after having copied only the two referenced Lua files in the script dir:

newLexer = require "llex_mk3"
newParser = require "lparser_mk3"

code = io.read "*all"
lexer = newLexer(code, "=string")
parser = newParser(lexer)

result = parser:parser()
dump(result)

Given input such as:

i = 1 + 2

it emits:

Begin table     log     :
1       is      -- TOP: begin
2       is      >> open_func
3       is
4       is      chunk:
5       is      -- STATEMENT: begin 'expr' line=1
6       is      prefixexp: <name>
7       is          str_checkname: 'i'
8       is          singlevar: name='i'
9       is      expr_stat: assignment k='VLOCAL'
10      is      assignment: '=' -- RHS elements follows
11      is      >> explist1: begin
12      is      expr:
13      is      simpleexp: <number>=1
14      is      >> subexpr: binop='+'
15      is      simpleexp: <number>=2
16      is      << subexpr: -- evaluate
17      is      << explist1: end
18      is      -- STATEMENT: end 'expr'
19      is
20      is      << close_func
21      is      -- TOP: end
end table       log     .

which does show me a lot about how the code is parsed. If I wanted to create call backs in a SAX-like fashion,, what would be a good way to go about this?

It seems to me initially, after some brief glancing at the code, that I would need to overide the log method and do my own Lua regexp based string parsing of the logged output to figure out what's going on. ALl the essential info is there all be it in an unstructured form, in that it is one long string, rather than several small ones. In fact overriding the log function with a debug printer as in:

parser.log = function ( ... ) print( ... ) end

Produces much the same output as above, the major difference being access to the parser object as a table. Which reminds me, I have a feeling this re-parsing of the logged output might not be the *right* way to do things, might it?

Ah, I think I got it now rendering the post rather useless. Looking at how the parser catenates strings for logging, it does of course have state based on which the output is generated, and it is accessing this parser state that would make writing a simple function dispatch system so much easier i.e. avoiding the need for re-parsing the log. My question is, how bad form is it if I look at what fields are used in generating the log and directly access these fields in my own log method as I see fit? If they are locals rather than object fields then ummm I reckon I'd need to access the callers namespace then, too. Technically overriding log is still an object method but it is also my own code, not really extending the parser per se. This introduces a dependencey on the parser internals. but at this point in which I'm trying to figure out whether attempting to improve Lua code read outs for screen reader users like me is worth it in the first place, even that quick n dirty solution would probably do fine. In fact I think I'll do just that.

Also, in Perl stuff is private by contract unless you rely on lexical closure, i.e. private implicitly if not mentioned in the module documentation. But in Lua, I'm not sure if the attitude is the same? I guess it is since Lua is even more runtime checked than Perl is, even strict is a runtime rather than compile time thingy.

--
With kind regards Veli-Pekka Tätilä