lua-users home
lua-l archive

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


> I guess the correct syntax would be more like
> 
>        fieldlist --> [ lfieldlist ] [ ';' [ ffieldlist ] ]
>                   |  [ ffieldlist ] [ ';' [ lfieldlist ] ]
> 

You mean:

  tableconstuctory --> '{' fieldlist '}'
         fieldlist --> [ lfieldlist ] [ ';' [ ffieldlist ] ]
                    |  ffieldlist [ ';' [ lfieldlist ] ]

This eliminates the ambiguity of how to parse an empty expression.

I've been giving more thought on how to make the manual better.  On
the subject of tables, one thing you could do is name the parts of a
table.  For example, you could state that a table maps keys to values,
where a key is any non-nil value.  The association of a key with a
value could be called a mapping.  Now when you come to give the
grammar, you can call an ffield something much more descriptive.  It
is a mapping field.

I have some other suggestions for improving the grammar in addition to
using more descriptive names for nonterminals.  I suggest separating
name components with the underscore character just as Lua allows one
to do in names.  More substantially, I suggest writing the grammar in
in a form closer to what would be used by a language implementor.  In
particular, use a notation that requires only a bound amount of
lookahead.  Finally, don't forget to note how to resolve any
ambiguities in the language.

----------------------------------------------

block	--> { stmt [ ';' ] } [ finish [ ';' ] ]

stmt	--> var { ',' var } '=' exprs -- see simp_expr definition for var
	 |  call	      	      -- see simp_expr definition for call
	 |  DO block END
	 |  WHILE expr DO block END
         |  REPEAT block UNTIL expr
	 |  IF expr THEN block 
	      { ELSEIF expr THEN block }
	      [ ELSE block ] END
	 |  FOR name '=' expr ',' expr [ ',' expr ] DO block END
	 |  FOR name ',' name IN expr DO block END
	 |  FUNCTION func_name '(' [ params ] ')' block END
	 |  LOCAL name { ',' name } [ '=' exprs ]

finish	--> RETURN [ exprs ] |  BREAK [ name ]

func_name --> name { '.' key } [ ':' key ]

key     --> name | AND | BREAK | DO | END | ELSE | ELSEIF
         | FOR | FUNCTION | GLOBAL | IF | IN | LOCAL | NIL
         | NOT | OR | RETURN | REPEAT | THEN | UNTIL | WHILE

params  --> '...' | name { ',' name } [ ',' '...' ]

exprs	--> expr { ',' expr }

expr    --> simp_expr | expr binop expr | unop expr

simp_expr --> primary
         | name				-- implies simp_expr is a var
         | simp_expr '[' expr ']'	-- implies simp_expr is a var
         | simp_expr '.' key		-- implies simp_expr is a var
         | simp_expr [ ':' key ] args	-- implies simp_expr is a call

primary --> NIL | number | literal | '%' name | table_cons
	 | FUNCTION '(' [ params ] ')' block END | ( expr ) 

table_cons --> '{' fields '}

fields  --> [ expr_fields ] [ ';' [ mapping_fields ] ]
         |  mapping_fields [ ';' [ expr_fields ] ]

expr_fields --> exprs [ ',' ]
 
mapping_fields --> mapping_field { ',' mapping_field }  [ ',' ]

mapping_field --> '[' expr ']' '=' expr | key '=' expr

binop   --> ...

unop    --> '-' | NOT

--------------------------------------------

Note that left parenthesis, left brace, and literals are preferentially
treated as arguments rather than as starting a new expression.
Without this rule, the grammar is ambiguous.

------------------------------------------------------------------

The latest version of lsc.y reflects the grammar above.  This program
seems to accept the same languages as does the 4.1 alpha parser, so
the grammar should be accurate, well, except for typos and things.

John